【Java学习—(22)反射】

(点击跳转即可哦)

java学习专栏

LeetCode刷题专栏



反射

反射:

JVM运行时,

对于JVM中任何一个类,都能动态获取该类的所有属性和方法。

对于JVM中任何一个对象,都能动态调用该对象的属性和方法

动态获取信息以及调用对象机制称为 反射机制

反射基本信息

Java程序中许多对象在运行时会出现两种类型:运行时类型(RTTI)和编译时类型,

例如Person p = new Student();

这句代码中p在编译时类型为Person,运行时类型为Student。

运行时明确该引用到底是啥类型就可以通过反射机制。

反射相关的类

java.lang.reflect包下的

类名用途
Class类代表类的实体,在运行的Java应用程序中表示类和接口
Field类代表类的成员变量/类的属性
Method类代表类的方法
Constructor类代表类的构造方法

Class类:反射核心类,使用Class关键字,包括数组,包括接口编译后生成的class文件就对于一个唯一的class对象,由JVM产生,使用这个class对象就可以获取该类的所有信息

Field类:反射调用类中的成员/类属性

Method类:反射调用类中的成员/类方法

Constructor类:反射调用构造方法


1 获取该类的class对象

1 无论要通过反射机制干啥事,首先第一步要获取该类的class对象(由JVM产生的,全局唯一)

a. 调用Class.forName(类的全名称,包名.类名)

b. 调用类名称.class属性 eg:Student.class

c. 通过该类的任意对象的getClass方法()

public class Test{
    public static void main(String[] args) throw Exception{
        //1 获取Student 类的class对象
        Class<Student> c1 = (Class<Student>) class.forName("包名.类名");
        //2 通过类名称.class 获取class
        Class<Student> c2 = Student.class;
        //3 通过Student对象的getClass方法
        Class<Student> c3 = (Class<Student>) new Student().getClass();
    }
}
Person per = new Student();
//通过反射 就可以看到他运行时类型 RTTI
System.out.println(per.getClass());

2 通过反射调用构造方法

以下方法返回值为 Constructor相关

//获得该类中参与类型匹配的公有构造方法
getConstructor(Class...<?> parameterTypes)
    
//获得该类的所有公有构造方法
getConstructors()
    
//获得该类中与参数类型匹配的构造方法
getDeclaredConstructor(Class...<?> parameterTypes)
    
//获得该类所有构造方法
getDeclaredConstructors()

普通的get 只能获取public权限的方法或者属性

getDeclared…()可以获取所有权限的方法或者属性

Class<Student> cls = Student.class;
//获得所有public权限的构造方法
Constructor[] constructors = cls.getConstructors();
//打印
for(Constructor constructor : constructors){
	System.out.println(constructor);
}

//获得该类所有构造方法
Constructor[] cs = cls.getDeclaredConstructors();
//打印
for(Constructor constructor : cs){
	System.out.println(constructor);
}

Class<Student> cls = Student.class;
//获取指定类型的有参构造
ConStructor<Student> constructor = cls.getDeclaredConstructor(String.class,String.class,int.class);
Students student = constructor.newInstance("姓名""性别"18)System.out.println(student);

破坏封装产生对象

Class<Student> cls = Student.class;
//获取指定类型的有参构造
ConStructor<Student> constructor = cls.getDeclaredConstructor(String.class);
//破环封装,通过反射破坏private封装,调用私有构造方法
constructor.setAccessible(true);
Student student = constructor.newInstance("姓名");
System.out.println(student);

3 通过反射调用普通方法

以下方法返回值为 Method相关

//获得该类某个公有的方法
getMethod(String name, Class...<?> parameterTypes) 

    
//获得该类所有公有的方法
getMethods() 
    
    
//获得该类某个方法
getDeclaredMethod(String name, Class...<?> parameterTypes)
    
    
//获得该类所有方法
getDeclaredMethods() 

通过Method类调用相应方法

public Object invoke(Object obj,Object... args)

第一个参数:通过哪个对象调用这个方法,普通方法必须通过对象调用,若是静态方法,这里传入null

第二个参数:要调用方法的具体参数

public static void test(){
	System.out.println("Student类的静态方法")
}
Class<Student> cls = Student.class;
//获取调用方法的Method对象
Method method = cls.getDeclaredMethod(test);
//test就是静态方法,无须产生Student对象
method.invoke(null);
//输出结果:Student类的静态方法

public void fun(String msg){
	System.out.println(this.name + "Student类的普通方法");
    System.out.println(msg);
}
Class<Student> cls = Student.class;
Method method2 = cls.getDeclaredMethod("fun",String.class);
//产生Student对象
Student student = new Student("姓名","性别",18);
method2.invoke(student,"电脑修好了");
//       通过哪个对象调用的,  具体的参数

常用获得类中属性相关的方法

以下方法返回值为 Field相关

getField(String name) 			//获得某个公有的属性对象
getFields() 					//获得所有公有的属性对象
getDeclaredField(String name)	//获得某个属性对象
getDeclaredFields() 			//获得所有属性对象
//Field类的方法

//通过obj对象获取相关属性的值,属性为静态属性时则传入null
public Object get(Object obj)
    
//通过obj对象修改相关属性的值
public void set(Object obj,Object value)

//获取要拿到的属性Field对象
Field field = cls.getDeclared("country");//静态
System.out.println(field.get(null));

Field field1 = cls.getDeclared("age");
Student student = new Student("姓名","性别",18);
System.out.println(field1.get(student));  //输出结果为 18
field1.set(student,20);
System.out.println(field.get(student));//输出结果是 20

要是对大家有所帮助的话,请帮我点个赞吧。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值