Reflect 反射:
所有类都是Object的子类
所有类的对象都是Class类的实例
反射:在程序运行期间,对于任意一个类,我们都能知道这个类中所有的属性和方法(包含私有的),这种动态的获取类的信息和动态的调用对象的方法或者属性的功能====>Java反射机制
但是破坏了封装的安全性
为什么需要完整限定名:
完整限定名=包名+类名
在同一个包中不允许出现相同的类
确保类是唯一的
1.Class.forName("完整限定名").getName()
2.类名.Class.getName()
3.对象名.getClass.getName()
@Test
public void Test01(){
try {
System.out.println("第一种式:"+Class.forName("demo3.fanshe.Student").getName());
System.out.println("第二种方式:"+Student.class.getName());
System.out.println("第三种方式:"+new Student().getClass().getName());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
@Test
public void Test02(){
try {
Class c = Class.forName("demo3.fanshe.Student");
System.out.println("Student类所在的包:"+c.getPackage().getName());
System.out.println("Student类完整限定名:"+c.getName());
System.out.println("Student类简写的类名:"+c.getSimpleName());
int num = c.getModifiers();
String result = Modifier.toString(num);
System.out.println("获取类的修饰符"+result);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* getFields(): 只能获取public修饰的字段
* getDeclaredFields():所有字段的集合
*/
@Test
public void Test03(){
try {
Class c = Class.forName("demo3.fanshe.Student");
Field[] fields = c.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
System.out.print(fields[i].getName());
System.out.println("对应的修饰符是:"+Modifier.toString(fields[i].getModifiers()));
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* c.getMethods() :获取所有public修饰的方法
* c.getDeclaredMethods():获取所有的方法
*/
@Test
public void Test04(){
try {
Class c = Class.forName("demo3.fanshe.Student");
Method[] methods = c.getDeclaredMethods();
for (int i = 0; i < methods.length; i++) {
System.out.println(methods[i].getName());
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
@Test
public void Test05(){
try {
Class c = Class.forName("demo3.fanshe.Student");
Student stu = (Student) c.newInstance();
// stu.sex 获取不到私有的属性和私有方法
Field field = c.getDeclaredField("sex");
// 打开访问私有属性或者方法的开关
field.setAccessible(true);
System.out.println(field.get(stu));
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
}
}
@Test
public void Test06(){
try {
Class c = Class.forName("demo3.fanshe.Student");
Student stu = (Student) c.newInstance();
Method method = c.getDeclaredMethod("getSum", double.class);
// 打开访问私有属性或者方法的开关
method.setAccessible(true);
double result = (double) method.invoke(stu, 50.0);
System.out.println(result);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
类的生命周期(面试题):
01.加载 : 找到并加载我们的.class文件
02.连接
001.验证
002.准备 为类中所有静态数据开辟空间,并且赋予 默认值
003.解析 把类中所有的符号引用, 转换成直接引用
03.初始化
类中所有静态数据开辟空间,并且赋予 初始值