阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

反射机制

237次阅读
没有评论

共计 4163 个字符,预计需要花费 11 分钟才能阅读完成。

1、反射概念

反射就是在程序运行的过程中,动态的创建对象。
只要知道该类的类名称,就可以使用它的字节码对象创建该类的一个对象。对于这个类中的任何一个成员或者属性,我们都可以访问或者使用它。

2、Class 对象

2.1、什么是字节码文件?

字节码文件,也就是以.class 结尾的文件,他是 Java 中的类经过编译之后生成的字节码数据文件!该文件最终会被 JVM 加载进内存。

2.2、什么是字节码对象?

前面说过,JVM 最终会把字节码文件加载进内存,该文件进 JVM 内存之后,Java 就会把他当做是一个字节码对象!因为 Java 是一门面向对象的语言,在 Java 的世界中,所有的东西都是对象,自然也包括该字节码文件了!

反射机制

2.3、字节码对象的获取方式

(1)Object 对象的 getClass 方法
(2)类型.class 属性
(3)Class 类的静态方法–>forName()

public static void main(String[] args) throws Exception {// 方式一
//Object getClass()方法
Person p = new Person();
Class clazz1 = p.getClass();
// 方式二
// 类型.class 属性
Class clazz2 = Person.class;
Class clazz3 = Student.class;
Class clazz4 = int.class;// 基本数据类型也有字节码对象
// 方式三
//Class 类的静态方法 ---> forName("类的完整路径");
// 注意:这里要用全路径名
Class clazz5 = Class.forName("Test.Student");
// 思考:同一个类的字节码对象,在程序的一次运行过程中会被获取几次?
}

2.4、Class 对象的组成

Class 对象主要由以下几部分组成:

(1)若干 Constructor 对象

(2)若干 Method 对象

(3)若干 Field 对象

反射机制

3、Constructor 对象

3.1、Constructor 概述

首先思考一个问题,构造器的作用是什么?构造器的作用就是构造一个对象!我们平时用 new 关键来创建一个类的对象,new 后面跟着的其实就该类的构造方法!如下图所示:

反射机制

构造器是用来构建对象的,同样的,构造器对象 /Constructor 对象也是用来构建对象的!

public class Person {private String name;
private int age;
public Person() { }
public Person(String name, int age) {this.name = name;
this.age = age;
}
@Override
public String toString() {return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}

3.2、得到构造器对象

(1)公共 构造器的获取方法

getConstructors()

public static void main(String[] args) throws Exception {// 获得字节码对象
Class clazz = Person.class;
// 得到所有公共构造器对象
Constructor[] constructors = clazz.getConstructors();
for (Constructor constructor : constructors) {System.out.println(constructor);
}
}

(2)所有构造器的获取方式

getDeclaredConstructors()

public static void main(String[] args) throws Exception {// 获得字节码对象
Class clazz = Person.class;
// 得到所有公共构造器对象
Constructor[] constructors = clazz.getDeclaredConstructors();
for (Constructor constructor : constructors) {System.out.println(constructor);
}
}

(3)获得指定公共构造器

getConstructor(Class… parameter);

public static void main(String[] args) throws Exception {// 获得字节码对象
Class clazz = Person.class;
// 得到所有公共构造器对象
Constructor constructor = clazz.getConstructor(String.class,int.class);
// 参数是可变形参,参数类型是该参数类型的字节码对象 --?Class… parameter
System.out.println(constructor);
}
public static void main(String[] args) throws Exception {// 获得字节码对象
Class clazz = Person.class;
// 得到所有公共构造器对象
Constructor constructor = clazz.getConstructor();
// 参数是可变形参,参数类型是该参数类型的字节码对象 --?Class… parameter
System.out.println(constructor);
}

(4)获得指定非公共构造器对象

getDeclaredConstructor(Class… parameter);

public static void main(String[] args) throws Exception {// 获得字节码对象
Class clazz = Person.class;
// 得到所有公共构造器对象
Constructor constructor = clazz.getDeclaredConstructor(String.class,int.class);
// 参数是可变形参,参数类型是该参数类型的字节码对象 --?Class… parameter
System.out.println(constructor);
}
public static void main(String[] args) throws Exception {// 获得字节码对象
Class clazz = Person.class;
// 得到所有公共构造器对象
Constructor constructor = clazz.getDeclaredConstructor();
// 参数是可变形参,参数类型是该参数类型的字节码对象 --Class… parameter
System.out.println(constructor);
}

3.3、用构造器对象创建该类实例

newInstance(Object… initargs));

反射机制

4、Method 对象

4.1、Method 对象的获取

getMethods()—> 得到所有公共的方法对象
getDeclaredMethods()-? 得到所有的方法对象
getMethod(String name,Class… parameter); 得到指定的公共方法对象
getDeclaredMethod(String name,Class… parameter); 得到指定的任意方法对象

public static void main(String[] args) throws Exception {// 获得字节码对象
Class clazz = Person.class;
// 得到所有公共的方法对象
Method[] methods = clazz.getMethods();
// 得到所有方法对象
Method[] methods2 = clazz.getDeclaredMethods();
// 得到指定的公共方法对象
Method method = clazz.getMethod("method", String.class);
// 得到指定的非公共方法对象
Method method2 = clazz.getDeclaredMethod("method", String.class);
}

4.2、Method 对象的使用

invoke(Object obj, Object… args);

public static void main(String[] args) throws Exception {// 获得字节码对象
Class clazz = Person.class;
// 得到指定的公共方法对象
Method method = clazz.getMethod("method", String.class);
// 正常调用方法的格式是:对象名. 方法名(参数)
// 反射执行方法的格式:方法对象.invoke(方法所属对象, 实参列表);
method.invoke(clazz.newInstance(), "haha");
}

5、Field 对象

5.1、获取 Field 对象

public static void main(String[] args) throws Exception {// 获得字节码对象
Class clazz = Person.class;
// 得到指定的 Field
Field field = clazz.getField("name");
System.out.println(field);
// 得到 Field 对象的值
System.out.println(field.get(clazz.newInstance()));
}

补充:

Class 的 newInstance 方法

​ 底层调用 无参的公共 的 Constructor 对象的 newInstance 方法创建该类的实例

5.2、设置 Field 对象的值

public static void main(String[] args) throws Exception {// 获得字节码对象
Class clazz = Person.class;
// 得到指定的 Field
Field field = clazz.getField("name");
// 给指定的 Field 对象设置值
Object object = clazz.newInstance();
field.set(object, "zhangsan");
// 获取值
System.out.println(field.get(object));
}

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-06-06发表,共计4163字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中