前言
java许多对象运行时有两种类型,一种由声明对象时实用的类型决定,称作 编译时类型,另一种由实际赋值给对象对象的类型决定,即运行时类型
Animal animal=new Tiger();
//其中编译时类型为animal,运行时类型为Tiger。
当编译时无法获知对象信息,程序就只能依靠运行时获知对象与类的实际信息,反射就起到运行时发现对象和类的真实信息的作用。
一、Java反射API
- Class类:可以获取类的属性,方法等信息,是java反射的核心类
- Constructor类:表示类的构造方法
- Method类:表示类的方法,可以用了获取类中的方法信息或者执行方法
- Field类:表示类的乘以变量
二、java反射使用步骤
Class对象是反射的核心,获取class对象,使用反射API操作:
package com.vo;
/**
* @description: java反射机制测试类
* @author: hfx
* @date : 2021/2/26
*/
public class TestVo {
private int userId;
private String userName;
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public TestVo(int userId, String userName) {
this.userId = userId;
this.userName = userName;
}
public TestVo() {
}
}
package com.testJavaMessage;
import com.vo.TestVo;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* @description: 测试
* @author: hfx
* @date : 2021/2/26
*/
public class ReflectTest {
public static void main(String[] args) {
//class获取的三种方式
TestVo testVo=new TestVo();
//1.对象.getClass()
Class clasz=testVo.getClass();
//2.对象.class
Class clasa=TestVo.class;
Class aClass= null;
try {
//3.只需要知道一个类的全路径
aClass = Class.forName("com.vo.TestVo");//最安全,性能最好 只需要知道一个类的全路径
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//获取aClass对象的所有方法信息
Method[] mt=aClass.getDeclaredMethods();
for (Method metho:mt) {
System.out.println("##普通方法:##"+metho);
}
//获取aClass对象的所有成员属性信息
Field[] field=aClass.getDeclaredFields();
for (Field fl:field) {
System.out.println("属性+++:"+fl);
}
//获取aClass对象的所有构造方法信息
Constructor[] constructor=aClass.getDeclaredConstructors();
for (Constructor constructor1 : constructor) {
System.out.println("---构造方法:---"+constructor1);
}
}
}
//输出
##普通方法:##public java.lang.String com.vo.TestVo.getUserName()
##普通方法:##public int com.vo.TestVo.getUserId()
##普通方法:##public void com.vo.TestVo.setUserId(int)
##普通方法:##public void com.vo.TestVo.setUserName(java.lang.String)
属性+++:private int com.vo.TestVo.userId
属性+++:private java.lang.String com.vo.TestVo.userName
---构造方法:---public com.vo.TestVo(int,java.lang.String)
---构造方法:---public com.vo.TestVo()
总结
java反射机制能够在我们只知道对象名称和地址时,不需要具体找到某个类,
可以通过反射机制获取该类的属性和方法,更加灵活地使用对象,同时,这也表明在类创建时设置private ,protect等访问修饰符,不一定能阻拦其他地方对象的获取,这个可以自行尝试