什么是反射:
反射就是通过获取class字节码文件对象/Class的类对象,
获取该字节码文件对象中的成员变量,构造方法,和成员方法
Field: 简称成员变量 (Field 提供有关类或接口的单个字段的信息,以及对它的动态访问权限。
反射的字段可能是一个类(静态)字段或实例字段。)
Constructor:简称构造方法:提供关于类的单个构造方法的信息以及对它的访问权限。
Method:简称成员方法:类或接口上单独某个方法(以及如何访问该方法)的信息
面试题:
如何获取class字节码文件对象/Class的类对象
三种方式来获取这个class字节码文件对象:
1)Object中的getClass()
2)任何数据类型的静态属性class
3)Class类中的方法:
forName(String className)
创建Person对象
Person p = new Person() ;
System.out.println(p) ;
反射常用的方法
forName()获取该类的字节码文件
getConstructors() 获取表示类的所有公共方法
getdeclaredConstructos 获取所有的方法
getConstructor()获取单个构造方法
public T newInstance(Object... initargs):initrgs:实际参数
表示示的构造方法来创建该构造方法的声明类的新实例,并用指定的初始化参数初始化该实例
举例:
public void setAccessible(boolean flag)值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查
举例:
反射就是通过获取class字节码文件对象/Class的类对象,
获取该字节码文件对象中的成员变量,构造方法,和成员方法
Field: 简称成员变量 (Field 提供有关类或接口的单个字段的信息,以及对它的动态访问权限。
反射的字段可能是一个类(静态)字段或实例字段。)
Constructor:简称构造方法:提供关于类的单个构造方法的信息以及对它的访问权限。
Method:简称成员方法:类或接口上单独某个方法(以及如何访问该方法)的信息
面试题:
如何获取class字节码文件对象/Class的类对象
三种方式来获取这个class字节码文件对象:
1)Object中的getClass()
2)任何数据类型的静态属性class
3)Class类中的方法:
forName(String className)
forName("类路径")
举例:
public class ReflectDemo {
public static void main(String[] args) throws ClassNotFoundException {
//如何获得类字节码文件
Person p1=new Person();
Class c1 = p1.getClass();//class org.westos_2.Person
System.out.println(p1);
System.out.println(c1);
Person p2=new Person();
Class c2 = p2.getClass();
System.out.println(p2);
System.out.println(c2);
System.out.println(c1==c2);//代表类的字节码,类的字节码是唯一的
System.out.println(p1==p2);//内存从新开辟了空间
System.out.println("--------------------");
//静态的属性Class
Class c3=Person.class;
System.out.println(c3==c2);
//通常使用第三种方式
//forName:包名+类名
Class c4=Class.forName("org.westos_2.Person");
System.out.println(c3==c4);
}
}
通过字节码文件对象获取构造方法并使用.
创建Person对象
Person p = new Person() ;
System.out.println(p) ;
反射常用的方法
forName()获取该类的字节码文件
getConstructors() 获取表示类的所有公共方法
getdeclaredConstructos 获取所有的方法
getConstructor()获取单个构造方法
public T newInstance(Object... initargs):initrgs:实际参数
表示示的构造方法来创建该构造方法的声明类的新实例,并用指定的初始化参数初始化该实例
举例:
public class ReflectDemo1 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException {
Class c=Class.forName("org.westos_2.Person");
//获取公共构造方法
//Constructor[] con1 = c.getConstructors();
//获取所有的构造方法
Constructor[] con2 = c.getDeclaredConstructors();
for(Constructor c1:con2) {
System.out.println(c1);
}
//获取单个构造方法
Constructor cc = c.getConstructor();
System.out.println(cc);
//获取映射对象
Object o = c.newInstance();
System.out.println(o);
}
}
通过反射获取构造方法并使用
比如:有参构造的形式
Person p = new Person() ;
System.out.println(p) ;
举例:
public class ReflectDemo2 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
//获取person类的字节码对象
Class<?> c = Class.forName("org.westos_2.Person");
//获取单个构造方法(公共的,带三个参数的)
Constructor<?> con = c.getConstructor(String.class,int.class,String.class);
Object o = con.newInstance("曾轶可",25,"山东");
System.out.println(o);
}
}
private Person(String name) {
this.name = name ;
}
Person p = new Person("高圆圆") ;
System.out.println(p) ;
反射常用方法
getDeclaredConstructor()获取单个的私有方法public void setAccessible(boolean flag)值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查
举例:
public class ReflectDemo3 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
//获取字节码文件对象
Class<?> c = Class.forName("org.westos_2.Person");
//获取单个的私有方法
Constructor<?> con = c.getDeclaredConstructor(String.class);
con.setAccessible(true);
Object o = con.newInstance("曾轶可");
System.out.println(o);
}
}
注释:如果访问私有的构造方法时,必须使用对象名调用setAccessible()防止java对语言的检测
获取成员变量,并使用
public Field[] getDeclaredFields():获取当前字节码文件对象中所有的字段
public Field[] getFields()获取当前字节码文件中单个的成员变量
public Field getField(String name):获取的是公共的字段
public void set(Object obj,Object value)
参数1:表示给哪个对象设置当前字段的值
参数2:表示给当前获取的哪个Field对象的字段设置一个新的值
举例:
public class ReflectDemo1 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException {
//获取字节码文件
Class<?> c = Class.forName("org.westos_2.Person");
//获取字节码文件对象中的所有公共的成员变量
// Field[] fields = c.getDeclaredFields();
// Field[] fields = c.getFields();
// for(Field f:fields) {
// System.out.println(f);
// }
Constructor<?> con = c.getConstructor();
Object o = con.newInstance();
// System.out.println(o);
//获取Field类对象
Field f = c.getField("address");
f.set(o, "东京");
System.out.println(o);
System.out.println("--------------------");
Field f1 = c.getDeclaredField("name");
f1.setAccessible(true);
f1.set(o, "曾轶可");
System.out.println(o);
System.out.println("========================");
Field f2 = c.getDeclaredField("age");
f2.setAccessible(true);
f2.set(o, 28);
System.out.println(o);
}。
}
注释:不是私有的在调用方法时不需要添加declare。其调用的是所有的变量,包括私有。