JAVA反射

概念

反射:将类的各个组成部分封装为其他对象,此为反射机制

优点:

  1. 可以在程序运行过程中,操作这些对象。
  2. 可以解耦,提高程序的可扩展性。

使用方式

1. 获取Class对象方式

1.1 Class.forName(“全类名”)

将字节码文件加载进内存,返回Class对象。多用于配置文件,将类名定义在配置文件中。读取文件,加载类

1.2 类名.class

通过类名的属性class获取。多用于参数的传递

1.3 对象.getClass()

getClass()方法在Object类中定义着。多用于对象的获取字节码的方式

同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取的Class对象都是同一个

2. Class API

2.1 获取成员变量s

  • Field[] getFields() 获取所有public修饰的成员变量
  • Field getField(String name) 获取指定名称的成员变量 public修饰的
  • Field[] getDeclaredFields() 获取所有的成员变量,不考虑修饰符
  • Field getDeclaredField(String name) 获取指定名称的成员变量 不考虑修饰符

2.2 获取构造方法s

  • Constructor<?>[] getConstructors()
  • Constructor getConstructor(类<?>… parameterTypes)
  • Constructor getDeclaredConstructor(类<?>… parameterTypes)
  • Constructor<?>[] getDeclaredConstructors()

2.3 获取成员方法s

  • Method[] getMethods()
  • Method getMethod(String name, 类<?>… parameterTypes)
  • Method[] getDeclaredMethods()
  • Method getDeclaredMethod(String name, 类<?>… parameterTypes)

2.4 获取全类名

  • String getName()

3. 使用途径

class Person {
	private String name;
	public int age;

	public void eat () {
		...
	}
	public void eat (String param) {
		...
	}
	// 默认构造、有参构造、get与set、toString..
}
public static void main (String[] args) {
//	0. 获取Person类的Class对象
	Class personClass = Person.class;	// 这里用了上面的第二种方法

//	1. 获取当前Class对象的全部成员变量
	Field[] declaredFields = personClass.getDeclaredFields();
	for (Field declaredField : declaredFields) {
		System.out.println(declaredField );	
		// private java.lang.String cn.Person.name;
		// public int cn.Person.age;
	}
		Field field = personClass.getDeclaredField("name");
		field.setAccessible(true);	//修饰符为private时,操作其值需要过滤安全检查。即 暴力反射
		Person p = new Person();
		// get某个成员变量的值
		Object value = field.get(p);  // 此value即为 p.name 的值
		// set某个成员变量的值
		field.set(p, "张三");

// 2. 获取当前Class对象的构造方法
	  Constructor constructor = personClass.getConstructor(String.class, int.class);
       System.out.println(constructor); // public cn.Person(java.lang.String, int)
        //创建对象
        Object person = constructor.newInstance("张三", 23); // 有参构造器
        System.out.println(person); // Person{name='张三', age=23}
        Object person1 = constructor1.newInstance(); // 无参构造器 。 newInstance()是可变参的方法
        System.out.println(person1); // Person{name='null', age=0}
  		// 简化
  		Object person3 = personClass.newInstance();	// 打印结果和person1一样

// 3. 执行Class对象的方法
  		Method eat_method = personClass.getMethod("eat"); // 无参eat方法
  		// 执行方法
  		eat_method.invoke(p);	
  		Method eat_method2 = personClass.getMethod("eat", String.class); // 有参eat方法
        //执行方法
        eat_method2.invoke(p, "饭");
        //获取所有public修饰的方法
        Method[] methods = personClass.getMethods();
        for (Method method : methods) {
            String name = method.getName();
            System.out.println(name);
            //method.setAccessible(true); 同Field 暴力反射
        }

// 4. 获取类名
        String className = personClass.getName();
        System.out.println(className); // cn.Person
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值