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。其调用的是所有的变量,包括私有。

猜你喜欢

转载自blog.csdn.net/wt5264/article/details/80700631