是什么
简而言之,通过反射,我们可以在运行时获得程序或程序集中每一个类型的成员和成员的信息。程序中一般的对象的类型都是在编译期就确定下来的,而 Java 反射机制可以动态地创建对象并调用其属性,这样的对象的类型在编译期是未知的。所以我们可以通过反射机制直接创建对象,即使这个对象的类型在编译期是未知的
java中
(1)Java反射机制的核心是在程序运行时动态加载类并获取类的详细信息,从而操作类或对象的属性和方法。本质是JVM得到class对象之后,再通过class对象进行反编译,从而获取对象的各种信息
(2)Java属于先编译再运行的语言,程序中对象的类型在编译期就确定下来了,而当程序在运行时可能需要动态加载某些类,这些类因为之前用不到,所以没有被加载到JVM。通过反射,可以在运行时动态地创建对象并调用其属性,不需要提前在编译期知道运行的对象是谁
-
使用反射机制可以动态获取当前class的信息 比如方法的信息、注解信息、方法的参数、属性等
目的
第三方框架---创建对象 不是直接new 反射机制创建
目的:提供开发者能够更好封装框架实现扩展功能
优缺点
优点:在运行时获得类的各种内容,进行反编译,对于Java这种先编译再运行的语言,能够让我们很方便的创建灵活的代码,这些代码可以在运行时装配,无需在组件之间进行源代码的链接,更加容易实现面向对象。
缺点:
(1)反射会消耗一定的系统资源,因此如果不需要动态地创建一个对象,那么就不需要用反射;
(2)反射调用方法时可以忽略权限检查,因此可能会破坏封装性而导致安全问题。
(在一个类中 定义了一个私有属性/方法 反射机制破解私有属)
用途
反编译:.class-->.java
-
通过反射机制访问java对象的属性,方法,构造方法等
-
JDBC加载驱动连接 class.forname
Class.forName("com.mysql.jdbc.Driver"); // 动态加载mysql驱动
-
Spring容器框架IOC实例化对象
<bean id="mayikt" class="com.mayikt.UserEntity" />
-
自定义注解生效(反射+Aop)
-
第三方核心的框架 mybatis orm
例子
获取类的三种方式
package com.cyz.entity;
/**
* @Author lian-chen
* @Date 2021/7/16 8:51
*/
public class UserEntity {
private String userName;
private Integer userAge;
public String pubUserName;
public UserEntity(String userName, Integer userAge) {
System.out.println("执行有残构造函数userName:"+userName+","+userAge);
this.userName = userName;
this.userAge = userAge;
}
public UserEntity() {
System.out.println("执行无参构造函数");
}
private void toSay(){
System.out.println("私有方法");
}
private void toSayAny(String msg){
System.out.println("私有有参方法:"+msg);
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public Integer getUserAge() {
return userAge;
}
public void setUserAge(Integer userAge) {
this.userAge = userAge;
}
package com.cyz.test;
import com.cyz.entity.UserEntity;
/**
* @Author lian-chen
* @Date 2021/7/16 8:54
*/
public class Test01 {
public static void main(String[] args) throws IllegalAccessException, InstantiationException, ClassNotFoundException {
/**
* 反射机制 动态获取class 信息内容 类的名称 方法 属性
* UserEntity.java ---> UserEntity.class
*/
/**
* 获取class
*/
Class<UserEntity> userEntityClass = UserEntity.class;
/**
* 默认执行无参构造函数
*/
UserEntity userEntity = userEntityClass.newInstance();
/**
* 通过 Class.forName()
* 类的完整路径地址 包名+类名
*/
Class<UserEntity> userEntityClass2 = (Class<UserEntity>) Class.forName("com.cyz.entity.UserEntity");
System.out.println(userEntityClass == userEntityClass2);//true
UserEntity userEntity1 = userEntityClass2.newInstance();
System.out.println(userEntity==userEntity1);//false
/**
* 构造对象获取
*/
UserEntity userEntity2 = new UserEntity();
Class<UserEntity> userEntityClass3 = (Class<UserEntity>) userEntity2.getClass();
UserEntity userEntity3 = userEntityClass3.newInstance();
System.out.println(userEntityClass==userEntityClass3);//true
System.out.println(userEntity==userEntity2);//false
System.out.println(userEntity1==userEntity2);//false
System.out.println(userEntity1==userEntity3);//false
}
}
构造函数调用
package com.cyz.test;
import com.cyz.entity.UserEntity;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
/**
* @Author lian-chen
* @Date 2021/7/17 8:24
*/
public class Test02 {
/**
* 有参
* 无参
* 构造函数
*/
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
Class<UserEntity> userEntityClass = (Class<UserEntity>) Class.forName("com.cyz.entity.UserEntity");
/**
* 默认执行无参构造函数
*/
// UserEntity userEntity = userEntityClass.newInstance();
/**
* 调用有参构造函数
*/
Constructor<UserEntity> declaredConstructor = userEntityClass.getDeclaredConstructor(String.class, Integer.class);
UserEntity userEntity = declaredConstructor.newInstance("lian-chen", 18);
}
}
使用属性
package com.cyz.test;
import com.cyz.entity.UserEntity;
import java.lang.reflect.Field;
/**
* @Author lian-chen
* @Date 2021/7/17 8:32
*/
public class Test03 {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException {
Class<UserEntity> userEntityClass = (Class<UserEntity>) Class.forName("com.cyz.entity.UserEntity");
/**
* 获取共有的属性
*/
Field[] fields = userEntityClass.getFields();
for (Field field : fields) {
System.out.println(field);
/**
* public java.lang.String com.cyz.entity.UserEntity.pubUserName
*/
}
/**
* 获取公有及私有的属性
*/
Field[] declaredFields = userEntityClass.getDeclaredFields();
for (Field declaredField : declaredFields) {
System.out.println(declaredField);
/**
* private java.lang.String com.cyz.entity.UserEntity.userName
* private java.lang.Integer com.cyz.entity.UserEntity.userAge
* public java.lang.String com.cyz.entity.UserEntity.pubUserName
*/
}
/**
* 对象属性赋值 公有属性
*/
UserEntity userEntity = userEntityClass.newInstance();
// Field pubUserName = userEntityClass.getField("pubUserName");
Field pubUserName = userEntityClass.getDeclaredField("pubUserName");
pubUserName.set(userEntity,"lian-chen");
System.out.println(userEntity);
/**
* UserEntity{userName='null', userAge=null, pubUserName='lian-chen'}
*/
/**
* 私有属性 需要访问权限
*/
Field userName = userEntityClass.getDeclaredField("userName");
// 反射访问私有属性权限
userName.setAccessible(true);
userName.set(userEntity,"chen");
System.out.println(userEntity);
/**
* UserEntity{userName='chen', userAge=null, pubUserName='lian-chen'}
*/
}
}
使用方法
package com.cyz.test;
import com.cyz.entity.UserEntity;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* @Author lian-chen
* @Date 2021/7/17 8:44
*/
public class Test04 {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
Class<UserEntity> userEntityClass = (Class<UserEntity>) Class.forName("com.cyz.entity.UserEntity");
/**
* 获取父类及子类的所有公有方法
*/
Method[] methods = userEntityClass.getMethods();
for (Method method : methods) {
System.out.println(method);
/**
* public java.lang.String com.cyz.entity.UserEntity.toString()
* public java.lang.Integer com.cyz.entity.UserEntity.getUserAge()
* public void com.cyz.entity.UserEntity.setUserName(java.lang.String)
* public void com.cyz.entity.UserEntity.setUserAge(java.lang.Integer)
* public java.lang.String com.cyz.entity.UserEntity.getUserName()
* 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()
*/
}
/**
* 获取本类的所有公有及私有方法
*/
Method[] declaredMethods = userEntityClass.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
System.out.println(declaredMethod);
/**
* public java.lang.String com.cyz.entity.UserEntity.toString()
* public void com.cyz.entity.UserEntity.setUserName(java.lang.String)
* public void com.cyz.entity.UserEntity.setUserAge(java.lang.Integer)
* public java.lang.Integer com.cyz.entity.UserEntity.getUserAge()
* public java.lang.String com.cyz.entity.UserEntity.getUserName()
* private void com.cyz.entity.UserEntity.toSay()
*/
}
/**
* 获取公共方法
*/
UserEntity userEntity = userEntityClass.newInstance();
Method getUserName = userEntityClass.getMethod("getUserName");
Object invoke = getUserName.invoke(userEntity);
/**
* 获取私有方法
*/
Method toSay = userEntityClass.getDeclaredMethod("toSay");
// 设置访问权限
toSay.setAccessible(true);
Object invoke1 = toSay.invoke(userEntity);
/**
* 私有方法
*/
/**
* 获取有参方法
*/
Method toSayAny = userEntityClass.getDeclaredMethod("toSayAny", String.class);
toSayAny.