反射机制
反射
反射获取类的对象
package com.reflection;
//反射
public class Test02 {
public static void main(String[] args) throws ClassNotFoundException {
//通过反射获取类的class对象
Class c1 = Class.forName("com.reflection.user");
user user = new user();
user.setName("小明");
user.setAge(18);
user.setId(0001);
System.out.println(c1);
Class c2 = Class.forName("com.reflection.user");
Class c3 = Class.forName("com.reflection.user");
Class c4 = Class.forName("com.reflection.user");
//一个类在内存中只有一个class对象
//一个类被加载后,类的整个结构都会被封装在class对象中
System.out.println(c2.hashCode());
System.out.println(c3.hashCode());
System.out.println(c4.hashCode());
System.out.println(c1.getClass().getName());
System.out.println(c2.getClass().getName());
System.out.println(c3.getClass().getName());
System.out.println("============");
System.out.println(user.getClass().getName()+" "+user.getName()+" "+user.toString());
}
}
//定义实体类:pojo entity
class user {
private String name;
private int age;
private int id;
public user() {
}
public user(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public String toString() {
return "user{" +
"name='" + name + '\'' +
", age=" + age +
", id=" + id +
'}';
}
}
class类的创建方式
package com.reflection;
//测试class类的创建方式有哪些
public class Test03 {
public static void main(String[] args) throws ClassNotFoundException {
Person person = new Student();
System.out.println("这个人是:" + person.name);
//方式1:通过对象获得
Class c1 = person.getClass();
System.out.println(c1.hashCode());
//方式2:forName获得
Class c2 = Class.forName("com.reflection.Student");
System.out.println(c2.hashCode());
//方式3:通过类名.class获得
Class c3 = Student.class;
System.out.println(c3.hashCode());
//方式4:基本内置类型的包装类都有一个type属性
Class c4 = Integer.TYPE;
System.out.println(c4);
//获得父类类型
Class c5 = c1.getSuperclass();
System.out.println(c5);
}
}
class Person {
public String name;
public Person() {
}
public Person(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
'}';
}
}
class Student extends Person {
public Student() {
this.name = "学生";
}
}
class Teachers extends Person {
public Teachers() {
this.name = "老师";
}
}
所有类型的Class
package com.reflection;
import java.lang.annotation.ElementType;
//所有类型的Class
public class Test04 {
public static void main(String[] args) {
Class c1 = Object.class;//类
Class c2 = Comparable.class;//接口
Class c3 = String[].class;//一维数组
Class c4 = int[][].class;//二维数组
Class c5 = Override.class;//注解
Class c6 = ElementType.class;//枚举
Class c7 = Integer.class;//基本数据类型
Class c8 = void.class;//void
Class c9 = Class.class;//class
System.out.println(c1);
System.out.println(c2);
System.out.println(c3);
System.out.println(c4);
System.out.println(c5);
System.out.println(c6);
System.out.println(c7);
System.out.println(c8);
System.out.println(c9);
System.out.println("======");
int[] a = new int[10];
int[] b = new int[100];
//只要元素类型和维度一样,就是同一个Class
System.out.println(a.getClass().hashCode());
System.out.println(b.getClass().hashCode());
}
}
类的加载和初始化
- 加载:将class文件字节码内容加载到内存中,并将这些静态数据转换成方法区的运行时数据结构,然后生成一个代表这个类的java.lang.Class对象。
- 链接:将Java类的二进制代码合并到JVM的运行状态之中的过程
- 验证:确保加载的类信息符合JVM规范,没有安全方面的问题
- 准备:正式为类变量分配内存并设置类变量默认初始值的阶段,这些内存都将在方法区中进行分配
- 解析:虚拟机常量池的符号引用替换为直接引用的过程
- 初始化
- 执行类构造器
()方法的过程。类构造器 ()方法是由编译器自动收集类中所有变量的赋值动作和静态代码块中的语句合并产生的。 - 当初始化一个类的时候,如果发现其父类还没有进行初始化,则先触发父类的初始化。
- 虚拟机会保证一个类的类构造器
()方法在多线程环境中被正确加锁和同步
- 执行类构造器
package com.reflection;
public class Test05 {
public static void main(String[] args) {
A a = new A();
System.out.println(A.m);
}
}
class A {
static {
System.out.println("A类静态代码块初始化");
m = 300;
}
static int m = 100;
public A() {
System.out.println("A类的无参构造初始化");
}
}
结果:

代码及测试运行:
package com.reflection;
public class Test06 {
static {
System.out.println("main类被加载");
}
public static void main(String[] args) throws ClassNotFoundException {
//1、主动引用
Son son = new Son();
//2、反射也会产生主动引用
//Class.forName("com.reflection.Son");
//3、不会产生类的引用的方法
//System.out.println(Son.F);
//Son[] array = new Son[5];
//System.out.println(Son.m);
}
}
class Father {
static int F = 2;
static {
System.out.println("父类被加载");
}
}
class Son extends Father {
static {
System.out.println("子类被加载");
}
static int S = 100;
static final int m=101;
}
//1、主动引用
Son son = new Son();
结果:

//2、反射也会产生主动引用
Class.forName("com.reflection.Son");
结果:

//3、不会产生类的引用的方法
System.out.println(Son.F);
结果:

Son[] array = new Son[5];
结果:

System.out.println(Son.m);
结果:

类加载器
package com.reflection;
import java.util.concurrent.Callable;
public class Test07 {
public static void main(String[] args) throws ClassNotFoundException {
//获取系统类的加载器
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
System.out.println(systemClassLoader);
//获取系统类加载器的父类加载器--->扩展类加载器
ClassLoader parent = systemClassLoader.getParent();
System.out.println(parent);
//获取扩展类加载器的父类加载器--->根加载器(c/c++)
ClassLoader parent1 = parent.getParent();
System.out.println(parent1);
//测试当前类是哪个加载器加载的
ClassLoader classLoader = Class.forName("com.reflection.Test07").getClassLoader();
System.out.println(classLoader);
//测试JDK内置的类是谁加载的
classLoader = Class.forName("java.lang.Object").getClassLoader();
System.out.println(classLoader);
//如何获得系统类加载器可以加载的路径
System.out.println(System.getProperty("java.class.path"));
/**
*
* D:\Developer_tools\jdk1.8.0_202\jre\lib\charsets.jar;
* D:\Developer_tools\jdk1.8.0_202\jre\lib\deploy.jar;
* D:\Developer_tools\jdk1.8.0_202\jre\lib\ext\access-bridge-64.jar;
* D:\Developer_tools\jdk1.8.0_202\jre\lib\ext\cldrdata.jar;
* D:\Developer_tools\jdk1.8.0_202\jre\lib\ext\dnsns.jar;
* D:\Developer_tools\jdk1.8.0_202\jre\lib\ext\jaccess.jar;
* D:\Developer_tools\jdk1.8.0_202\jre\lib\ext\jfxrt.jar;
* D:\Developer_tools\jdk1.8.0_202\jre\lib\ext\localedata.jar;
* D:\Developer_tools\jdk1.8.0_202\jre\lib\ext\nashorn.jar;
* D:\Developer_tools\jdk1.8.0_202\jre\lib\ext\sunec.jar;
* D:\Developer_tools\jdk1.8.0_202\jre\lib\ext\sunjce_provider.jar;
* D:\Developer_tools\jdk1.8.0_202\jre\lib\ext\sunmscapi.jar;
* D:\Developer_tools\jdk1.8.0_202\jre\lib\ext\sunpkcs11.jar;
* D:\Developer_tools\jdk1.8.0_202\jre\lib\ext\zipfs.jar;
* D:\Developer_tools\jdk1.8.0_202\jre\lib\javaws.jar;
* D:\Developer_tools\jdk1.8.0_202\jre\lib\jce.jar;
* D:\Developer_tools\jdk1.8.0_202\jre\lib\jfr.jar;
* D:\Developer_tools\jdk1.8.0_202\jre\lib\jfxswt.jar;
* D:\Developer_tools\jdk1.8.0_202\jre\lib\jsse.jar;
* D:\Developer_tools\jdk1.8.0_202\jre\lib\management-agent.jar;
* D:\Developer_tools\jdk1.8.0_202\jre\lib\plugin.jar;
* D:\Developer_tools\jdk1.8.0_202\jre\lib\resources.jar;
* D:\Developer_tools\jdk1.8.0_202\jre\lib\rt.jar;
* D:\Projects\JavaSE\out\production\base_language;
* D:\Projects\JavaSE\javase\src\com\lib\commons-io-2.11.0.jar;
* D:\JetBrains\IntelliJ IDEA 2022.1.1\lib\idea_rt.jar
*
*/
}
}
结果:

获取类的运行时结构
package com.reflection;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
//获得类的信息
public class Test08 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
Class c1 = Class.forName("com.reflection.user");
//获得类的名字
System.out.println(c1.getName());//获得包名 + 类名
System.out.println(c1.getSimpleName());//获得类名
System.out.println("=======================================");
//获得类的属性
Field[] fields = c1.getFields();//只能找到public属性
for (Field field : fields) {
System.out.println(fields);
}
System.out.println("=======================================");
fields = c1.getDeclaredFields();//可以找到全部属性
for (Field field : fields) {
System.out.println(fields);
}
System.out.println("=======================================");
//获得指定属性的值
Field name = c1.getDeclaredField("name");
System.out.println(name);
System.out.println("=======================================");
//获得类的方法
Method[] methods = c1.getMethods();//获得子类及父类的所有public方法
for (Method method : methods) {
System.out.println(method);
}
System.out.println("---------------------------------------");
Method[] declaredMethods = c1.getDeclaredMethods();//获得子类的所有方法
for (Method method : declaredMethods) {
System.out.println(method);
}
System.out.println("=======================================");
//获得指定方法
Method getName = c1.getMethod("getName", null);
Method setName = c1.getMethod("setName", String.class);
System.out.println(getName);
System.out.println(setName);
System.out.println("=======================================");
//获得指定的构造器
Constructor[] constructors = c1.getConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
Constructor[] declaredConstructors = c1.getDeclaredConstructors();
for (Constructor declaredConstructor : declaredConstructors) {
System.out.println(declaredConstructor);
}
System.out.println("=======================================");
//获得指定的构造器
Constructor declaredConstructor = c1.getDeclaredConstructor(String.class,int.class,int.class);
System.out.println(declaredConstructor);
}
}
控制台输出结果:
com.reflection.user
user
=======================================
=======================================
[Ljava.lang.reflect.Field;@677327b6
[Ljava.lang.reflect.Field;@677327b6
[Ljava.lang.reflect.Field;@677327b6
=======================================
private java.lang.String com.reflection.user.name
=======================================
public java.lang.String com.reflection.user.toString()
public java.lang.String com.reflection.user.getName()
public int com.reflection.user.getId()
public void com.reflection.user.setName(java.lang.String)
public int com.reflection.user.getAge()
public void com.reflection.user.setAge(int)
public void com.reflection.user.setId(int)
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
---------------------------------------
public java.lang.String com.reflection.user.toString()
public java.lang.String com.reflection.user.getName()
public int com.reflection.user.getId()
public void com.reflection.user.setName(java.lang.String)
public int com.reflection.user.getAge()
public void com.reflection.user.setAge(int)
public void com.reflection.user.setId(int)
=======================================
public java.lang.String com.reflection.user.getName()
public void com.reflection.user.setName(java.lang.String)
=======================================
public com.reflection.user()
public com.reflection.user(java.lang.String,int,int)
public com.reflection.user()
public com.reflection.user(java.lang.String,int,int)
=======================================
public com.reflection.user(java.lang.String,int,int)
Process finished with exit code 0
动态创建对象执行方法
package com.reflection;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Test09 {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
//获得Class对象
Class c1 = Class.forName("com.reflection.user");
//构造一个对象
//user user = (user) c1.newInstance();//本质是调用了类的无参构造器
//System.out.println(user);
//通过构造器创建对象
//Constructor declaredConstructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
//user peanut = (user) declaredConstructor.newInstance("花生", 100, 18);
//System.out.println(peanut);
//通过反射调用普通方法
user user02 = (user) c1.newInstance();
//通过反射获取一个方法
Method setName = c1.getDeclaredMethod("setName", String.class);
//激活 (对象,"值")
setName.invoke(user02, "十三");
System.out.println(user02.getName());
System.out.println("=====================================");
//通过反射操作属性
user user03 = (user) c1.newInstance();
Field name = c1.getDeclaredField("name");
//不能直接操作私有属性,我们需要关闭程序的安全检测,属性或者方法的setAccessible(true)
name.setAccessible(true);
name.set(user03, "十三");
System.out.println(user03.getName());
}
}

反射方式性能分析
package com.reflection;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
//分析性能问题
public class Test10 {
public static void main(String[] args) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
test001();
test002();
test003();
}
//普通方式调用
public static void test001() {
user user = new user();
long startTime = System.currentTimeMillis();
for (int i = 0; i < 1000000000; i++) {
user.getName();
}
long endTime = System.currentTimeMillis();
System.out.println("普通方式执行十亿次:" + (endTime - startTime) + "ms");
}
//反射方式调用,未关闭检测
public static void test002() throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
user user = new user();
Class c1 = user.getClass();
Method getName = c1.getDeclaredMethod("getName", null);
long startTime = System.currentTimeMillis();
for (int i = 0; i < 1000000000; i++) {
getName.invoke(user, null);
}
long endTime = System.currentTimeMillis();
System.out.println("反射方式未关闭检测执行十亿次:" + (endTime - startTime) + "ms");
}
//反射方式调用,关闭检测
public static void test003() throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
user user = new user();
Class c1 = user.getClass();
Method getName = c1.getDeclaredMethod("getName", null);
getName.setAccessible(true);
long startTime = System.currentTimeMillis();
for (int i = 0; i < 1000000000; i++) {
getName.invoke(user, null);
}
long endTime = System.currentTimeMillis();
System.out.println("反射方式关闭检测执行十亿次:" + (endTime - startTime) + "ms");
}
}

获取泛型信息
package com.reflection;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
//通过反射获取泛型
public class Test11 {
public void test01(Map<String, user> map, List<user> list) {
System.out.println("test01");
}
public Map<String, user> test02() {
System.out.println("test02");
return null;
}
public static void main(String[] args) throws NoSuchMethodException {
Method method = Test11.class.getMethod("test01", Map.class, List.class);
Type[] genericParameterTypes = method.getGenericParameterTypes();
for (Type genericParameterType : genericParameterTypes) {
System.out.println("#" + genericParameterType);
if (genericParameterType instanceof ParameterizedType) {
Type[] actualTypeArguments = ((ParameterizedType) genericParameterType).getActualTypeArguments();
for (Type actualTypeArgument : actualTypeArguments) {
System.out.println(actualTypeArgument);
}
}
}
System.out.println("=============================================");
method = Test11.class.getMethod("test02", null);
Type genericReturnType = method.getGenericReturnType();
if (genericReturnType instanceof ParameterizedType) {
Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments();
for (Type actualTypeArgument : actualTypeArguments) {
System.out.println(actualTypeArgument);
}
}
}
}

获取注解信息
package com.reflection;
import java.lang.annotation.*;
import java.lang.reflect.Field;
//练习反射操作注解
public class Test12 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
Class<?> c1 = Class.forName("com.reflection.student2");
//通过反射获得注解
Annotation[] annotations = c1.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println(annotation);
}
//获得注解的value值
Table table = (Table) c1.getAnnotation(Table.class);
String value = table.value();
System.out.println(value);
//获得类指定的注解
Field f = c1.getDeclaredField("name");
field annotation = f.getAnnotation(field.class);
System.out.println(annotation.columnNum());
System.out.println(annotation.type());
System.out.println(annotation.length());
}
}
@Table("db_student")
class student2 {
@field(columnNum = "db_id", type = "int", length = 10)
private int id;
@field(columnNum = "db_age", type = "int", length = 10)
private int age;
@field(columnNum = "db_name", type = "varchar", length = 10)
private String name;
public student2() {
}
public student2(int id, int age, String name) {
this.id = id;
this.age = age;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "student2{" +
"id=" + id +
", age=" + age +
", name='" + name + '\'' +
'}';
}
}
//类名的注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Table {
String value();
}
//属性的注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface field {
String columnNum();
String type();
int length();
}


浙公网安备 33010602011771号