java 反射

为什么要使用反射?

反射是动态编译:运行时确定类型,绑定对象。动态编译最大限度发挥了java的灵活性,避免将程序写死到代码里,体现了多态的应用,可以降低类之间的藕合性。

例如: 实例化一个 person()对象, 不使用反射, new person(); 如果想变成 实例化 其他类, 那么必须修改源代码,并重新编译。使用反射: class.forName(“person”).newInstance(); 而且这个类描述可以写到配置文件中,如 **.xml, 这样如果想实例化其他类,只要修改配置文件的"类描述"就可以了,不需要重新修改代码并编译。

JAVA反射机制

是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.

Class类实例表示正在运行的Java应用程序中的类和接口。Class是普通类、接口、枚举类、数组等的抽象,即它们的类型就是Class,它们是Class的实例。

既然Class代表着类和接口,那么我们可以通过他的实例(字节码文件)来获取对应类或接口的信息,如:注解、修饰符、类型、类的名称、属性、方法、构造方法、直接父类和子类等,还有可以创建它的实例,但只能调用无参构造方法来创建。

获取构造方法

	getConstructors
	getDeclaredConstructors

创建对象

	newInstance()
	con.newInstance(“zhangsan", 20);

获取所有成员

	getFields,getDeclaredFields

获取单个成员

	getField,getDeclaredField

修改成员的值

	set(Object obj,Object value)  将指定对象变量上此 Field 对象表示的字段设置为指定的新值。

获取所有方法

	getMethods
	getDeclaredMethods

获取单个方法

	getMethod
	getDeclaredMethod

暴力访问

	method.setAccessible(true);

反射获得当前值

public class Student {

private String name;

private Integer age;

public String getName() {
	return name;
}
public void setName(String name) {
	this.name = name;
}
public Integer getAge() {
	return age;
}
public void setAge(Integer age) {
	this.age = age;
}

public String getMethod(){
	System.out.println("执行到了getMethod()");
	return "得到了方法";
}
@Override
public String toString() {
	return "Student [name=" + name + ", age=" + age + "]";
}

}

public class FansheClass {
public static void main(String[] args) throws Exception {

	Student student = new Student();
	student.setName("xzy");
	student.setAge(10);
	Class<? extends Student> class1 = student.getClass();
	Class<? extends Student> student1 = class1;

// 输出 student1:class javazbzn.Student
Method[] declaredMethods = student1.getDeclaredMethods();
for (Method method : declaredMethods) {
// 输出类下所有的方法体
}
Field[] declaredFields = student1.getDeclaredFields();
for (Field field : declaredFields) {
// 输出类下所有的属性变量
String name = field.getName();

        PropertyDescriptor descriptor = new PropertyDescriptor(name, student.getClass());
		
        Method readMethod = descriptor.getReadMethod();
        Object invoke = readMethod.invoke(student);
        
        System.out.println(invoke);
    //	       输出xzy 和  10
	}
	
}

}

反射参数使用

public class Main {
public static void main(String[] args) throws Exception{
//返回A的构造方法
Constructor c = A.class.getConstructor();
//返回A类的所有为public 声明的构造方法
Constructor[] cons = A.class.getConstructors();
//返回A类所有的构造方法,包括private
Constructor[] cons2 = A.class.getDeclaredConstructors();
//返回A类的第一个public 方法
Method m = A.class.getMethod(“say”);
//执行
m.invoke(A.class.newInstance(), null);
//返回A类所有的public 方法
Method[] ms = A.class.getMethods();
//返回A类所有的方法,包括private
Method[] allMs = A.class.getDeclaredMethods();
//返回A类的public字段
Field field = A.class.getField(“i”);
System.out.println(field.get(A.class.newInstance()));
//返回A类的static 字段
System.out.println(field.get(null));
}
}

class A{
public int i = 1;
public static int b = 2;
public A(){
System.out.println(“无参构造”);
}
private A(String s){
System.out.println(“有参构造”+s);
}

public void say(){
    System.out.println("say");
}

}

通过class 类路径反射获得当前对象

1 public class Reflect{
2
3 public static void main(String[] args) throws Exception {
4
5 Class c1 = Class.forName(“com.test.job.Person”);
6
7 //创建此Class对象所表示类的一个新实例,
8 //newInstance方法调用的是Person的空参数构造方法
9 Object o = c1.newInstance();
10 System.out.println(o.toString());
11 }

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值