1 java反射机制介绍
定义介绍: Java 反射机制在程序运行时,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性。这种 动态的获取信息 以及 动态调用对象的方法 的功能称为 java 的反射机制。
1.1 java代码的三种状态
这里以一个Person
类为例,具体代码如下:
1 | public class Person { |
1.2 获取class的3种方法
Class.forName("全类名")
,对应的是上图中的第一阶段(java源码阶段),如:Class.forName("com.reflect.entity.Person")
类名.class
,对应的是上图中的第二阶段(class类对象阶段),因为字节码文件已经加载带了内存,但是还没有调用,如:ReflectTest.class
对象.getClass()
,对应的是上图中的第三阶段,也就是Runtime阶段,因为此时已经创建了一个对象,如:person.getClass()
注意: 同一个*.class文件被重复或多次加载到内存中时,不会重复加载,只会加载一次
1 | Class cls1 = Class.forName("com.reflect.entity.Person"); |
1.3 class内部的属性
构造方法数组Constructor[]
- Constructor
getConstructor(Class<?>… parameterTypes) - Constructor<?>[] getConstructors() 获取所有由
public
修饰的构造方法 - Constructor
getDeclaredConstructor(Class<?>… parameterTypes) - Constructor<?>[] getDeclaredConstructors() 获取所有构造方法
- Constructor
成员属性Field[]
- Field getField(String name) 获取一个:只能获取由
public
修饰的成员属性 - Field[] getFields() 获取所有 :只能获取类中定义的由
public
修饰的成员属性 - Field[] getDeclaredFields() 获取所有属性:只要类中声明的,都会获取到
- Field getDeclaredField(String name) 获取一个:只要类中声明的,都会获取到
- Field getField(String name) 获取一个:只能获取由
成员方法Method[]
- Method[] getMethods() 获取全部由
public
修饰的成员方法 - Method getMethod(String name, Class<?>… parameterTypes)
- Method[] getDeclaredMethods() 获取所有
- Method getDeclaredMethod(String name, Class<?>… parameterTypes)
- Method[] getMethods() 获取全部由
获取类名
- String getName() 获取全类名
- String getSimpleName() 仅仅获取类名
2 举例
2.1 获取成员属性
(1)Field[] getFields()
得到所有由public
声明的成员属性
1 | Class cls1 = Class.forName("com.reflect.entity.Person"); |
运行结果:
public java.lang.String com.reflect.entity.Person.a
(2)Field getField(String name)
得到某一个具体的由public
声明的成员属性
1 | Class cls1 = Class.forName("com.reflect.entity.Person"); |
运行结果:
public java.lang.String com.reflect.entity.Person.a
(3) Field[] getDeclaredFields()
得到所有的类中已经声明的成员属性,不管修饰符
1 | Class cls1 = Class.forName("com.reflect.entity.Person"); |
运行结果:
private java.lang.String com.reflect.entity.Person.name
private java.lang.Integer com.reflect.entity.Person.age
private java.lang.String com.reflect.entity.Person.gend
public java.lang.String com.reflect.entity.Person.a
protected java.lang.String com.reflect.entity.Person.b
java.lang.String com.reflect.entity.Person.c
(4) Field getDeclaredField(String name)
得到某一个具体的类中已经声明的成员属性,不管修饰符
1 | Class cls1 = Class.forName("com.reflect.entity.Person"); |
运行结果:
private java.lang.String com.reflect.entity.Person.name
2.2 获取构造方法
(1) Constructor<?>[] getConstructors()
得到所有的由public
声明的构造方法
1 | Class cls1 = Class.forName("com.reflect.entity.Person"); |
运行结果:
public com.reflect.entity.Person()
public com.reflect.entity.Person(java.lang.String,java.lang.Integer,java.lang.String)
(2) Constructor getConstructor(Class<?>… parameterTypes)
得到某一个具体的由public
声明的构造方法
1 | Class cls1 = Class.forName("com.reflect.entity.Person"); |
运行结果:
public com.reflect.entity.Person(java.lang.String,java.lang.Integer,java.lang.String)
(3) Constructor getDeclaredConstructor(Class<?>… parameterTypes)
得到某一个具体的类中已经声明的任意构造方法,无论用什么修饰符修饰的都可以
1 | Class cls1 = Class.forName("com.reflect.entity.Person"); |
运行结果:
private com.reflect.entity.Person(java.lang.String,java.lang.String)
(4) Constructor<?>[] getDeclaredConstructors()
得到所有类中已经声明的构造方法,不管修饰符
1 | Class cls1 = Class.forName("com.reflect.entity.Person"); |
运行结果:
public com.reflect.entity.Person()
private com.reflect.entity.Person(java.lang.String,java.lang.String)
public com.reflect.entity.Person(java.lang.String,java.lang.Integer,java.lang.String)
2.3 获取成员方法
(1)Method[] getMethods()
只能得到所有由public
修饰的成员方法
1 | Class cls1 = Class.forName("com.reflect.entity.Person"); |
运行结果:
public java.lang.String com.reflect.entity.Person.toString()
public void com.reflect.entity.Person.eat()
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()
(2)Method getMethod(String name, Class<?>… parameterTypes)
只能得到某一个由public
修饰的方法
1 | Class cls1 = Class.forName("com.reflect.entity.Person"); |
运行结果:
public void com.reflect.entity.Person.eat()
(3) Method[] getDeclaredMethods()
可以获取类中所有声明的方法
1 | Class cls1 = Class.forName("com.reflect.entity.Person"); |
运行结果:
public java.lang.String com.reflect.entity.Person.toString()
private void com.reflect.entity.Person.laugh()
public void com.reflect.entity.Person.eat()
(4)Method getDeclaredMethod(String name, Class<?>… parameterTypes)
得到一个指定的类中声明的任何方法
1 | Class cls1 = Class.forName("com.reflect.entity.Person"); |
运行结果:
private void com.reflect.entity.Person.laugh()
3 用java反射机制写框架
框架功能介绍:
- 通过修改配置文件,修改要运行的类和类中的方法
- 当写好配置文件之后,将配置文件配置好的类和类中的方法运行
3.1 项目结构目录
3.2 具体代码
(1)Person.java
1 | package com.reflect.entity; |
(2)Student.java
1 | package com.reflect.entity; |
(3)pro.properties
1 | className=com.reflect.entity.Student # 要运行的类 |
(4)ReflectTest.java
1 | import com.reflect.entity.Person; |
写在最后
欢迎大家关注鄙人的公众号【麦田里的守望者zhg】,让我们一起成长,谢谢。