反射
一、介绍
1.什么是反射
反射就是把Java类中的__各个成分(构造器、属性和方法)映射成一个个的Java对象__,即在运行状态中:
- 对于任意一个类,都能知道这个类的所有属性和方法
- 对于任意一个对象,都能调用它的任意一个属性和方法
这种动态获取信息以及动态调用对象发放的功能叫Java的发射机制。
2.为什么产生反射
Java是一门静态类型语言,变量的类型在编译之前就需要确定,限制了程序的灵活性。
3.什么时候使用反射
当你获取不到类只能拿到类的路径字符串的时候,可以通过反射创建对象。
// 正常创建对象
User user = new User();
但是如果只能获取到User类的路径,怎么创建对象?
String str = "com.example.reflect.entity.User";
※必须是全路径
方法如下:
Class clazz = Class.forName(str);
User user = (User) clazz.newInstance();
完整代码:
public class UserTest {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
// 只能获取字符串 如何创建对象?
String str = "org.example.reflect.entity.User";
// 利用反射
Class clazz = Class.forName(str);
User user = (User) clazz.newInstance();
// --------
user.setName("孟祥宽");
user.setAge("18");
user.show();
}
}
运行结果:
二、Class类介绍
Class类是Java反射机制的起源和入口,用于获取与类相关的各种信息,提供了获取类信息的相关方法。
1.创建Class对象
1.1 通过Class关键字
// 方式一: 通过Class关键字
Class<User> clazz = User.class;
Object o = clazz.newInstance();
System.out.println(o instanceof User);
运行结果:
1.2 通过getClass()方法
// 方式二: 通过getClass方法
User user = new User();
Class<? extends User> clazz = user.getClass();
Object o = clazz.newInstance();
System.out.println(o instanceof User);
运行结果:
1.3 通过forName()方法
String str = "org.example.reflect.entity.User";
Class clazz = Class.forName(str);
2.Class类方法
// ---------------------- 获取构造器 ------------------
// 只能获取public修饰的所有构造器 --- 子类
Constructor<?>[] constructors = clazz.getConstructors();
System.out.println("突破限制前的构造器:" + Arrays.toString(constructors));
//突破限制 能获取非public修饰的所有构造器 --- 子类
Constructor<?>[] constructors2 = clazz.getDeclaredConstructors();
System.out.println("突破限制的构造器:" + Arrays.toString(constructors2));
// 获取单一public修饰的构造器
Constructor<? extends User> constructor = clazz.getConstructor();
System.out.println("user里的public修饰的无参构造器:" + constructor);
Constructor<? extends User> constructor2 = clazz.getDeclaredConstructor(String.class, int.class);
System.out.println("user里的突破限制后的有参构造:" + constructor2);
// 执行public修饰的构造器
Object o1 = constructor.newInstance();
constructor2.setAccessible(true);
User o2 = constructor2.newInstance("孟祥宽", 18);
System.out.println(o2.toString());
// -----------------------------------------------------
// ---------------- 获取字段 -----------------------
// 只能获取public修饰的所有字段 --- 子类和父类
Field[] fields = clazz.getFields();
System.out.println("突破限制前获取的属性:" + Arrays.toString(fields));
// 突破限制 能获取非public修饰的所有属性 --- 子类
Field[] fields2 = clazz.getDeclaredFields();
System.out.println("突破限制获取的属性:" + Arrays.toString(fields2));
// 获取public修饰的单一的属性 --- 子类和父类
Field dh = clazz.getField("dh");
System.out.println("user里的一个属性:" + dh);
// 获取非public修饰的单一的属性 --- 子类
Field age = clazz.getDeclaredField("age");
System.out.println("user里突破限制后获取的属性:" + age);
// 给属性赋值
dh.set(o1, "18943130289");
age.setAccessible(true);
age.set(o1, 18);
// -----------------------------------------------
// ------------------ 获取方法 ---------------------
// 只能获取public修饰的所有方法 --- 子类和父类
Method[] methods = clazz.getMethods();
System.out.println("突破限制前获取的方法:" + Arrays.toString(methods));
// 突破限制 能获取非public修饰的所有方法 --- 子类
Method[] methods2 = clazz.getDeclaredMethods();
System.out.println("突破限制获取的方法:" + Arrays.toString(methods2));
// 获取单个的方法 -- 子类和父类
Method setAge = clazz.getMethod("setAge", int.class);
System.out.println("user里的public修饰的方法:" + setAge);
// 获取非public修改时的方法
Method say = clazz.getDeclaredMethod("say");
System.out.println("user突破限制获取的方法:" + say);
// 执行方法
setAge.invoke(o1, 20);
System.out.println(o1.toString());
say.setAccessible(true);
say.invoke(o1);
// -------------------------------------------------
// ------------------------- 获取有泛型的属性或者方法中的泛型 -------------------------------
Field nums = clazz.getDeclaredField("nums");
Type genericType = nums.getGenericType();
System.out.println("泛型" + genericType);
Class<?> type = nums.getType();
System.out.println(type);
Method getNums = clazz.getMethod("getNums");
Type genericParameterTypes = getNums.getGenericReturnType();
System.out.println("方法中的泛型:" + genericParameterTypes);
运行结果:
突破限制前的构造器:[public org.example.reflect.entity.User(java.lang.String,java.lang.String,java.lang.String,java.lang.String,int), public org.example.reflect.entity.User()]
突破限制的构造器:[private org.example.reflect.entity.User(java.lang.String,int), public org.example.reflect.entity.User(java.lang.String,java.lang.String,java.lang.String,java.lang.String,int), public org.example.reflect.entity.User()]
user里的public修饰的无参构造器:public org.example.reflect.entity.User()
user里的突破限制后的有参构造:private org.example.reflect.entity.User(java.lang.String,int)
User{name='孟祥宽', age=18, xb='null', dh='null'}
突破限制前获取的属性:[public java.lang.String org.example.reflect.entity.Person.dh]
突破限制获取的属性:[private java.lang.String org.example.reflect.entity.User.name, private int org.example.reflect.entity.User.age, private java.util.Map org.example.reflect.entity.User.nums]
user里的一个属性:public java.lang.String org.example.reflect.entity.Person.dh
user里突破限制后获取的属性:private int org.example.reflect.entity.User.age
突破限制前获取的方法:[public java.lang.String org.example.reflect.entity.User.toString(), public java.lang.String org.example.reflect.entity.User.getName(), public void org.example.reflect.entity.User.setName(java.lang.String), public void org.example.reflect.entity.User.setAge(int), public int org.example.reflect.entity.User.getAge(), public java.util.Map org.example.reflect.entity.User.getNums(), public void org.example.reflect.entity.User.setNums(java.util.Map), public void org.example.reflect.entity.User.show(), public java.lang.String org.example.reflect.entity.Person.getDh(), public void org.example.reflect.entity.Person.setMz(java.lang.String), public void org.example.reflect.entity.Person.setXb(java.lang.String), public void org.example.reflect.entity.Person.setDh(java.lang.String), public java.lang.String org.example.reflect.entity.Person.getMz(), public java.lang.String org.example.reflect.entity.Person.getXb(), 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 org.example.reflect.entity.User.toString(), public java.lang.String org.example.reflect.entity.User.getName(), public void org.example.reflect.entity.User.setName(java.lang.String), public void org.example.reflect.entity.User.setAge(int), private void org.example.reflect.entity.User.say(), public int org.example.reflect.entity.User.getAge(), public java.util.Map org.example.reflect.entity.User.getNums(), public void org.example.reflect.entity.User.setNums(java.util.Map), public void org.example.reflect.entity.User.show()]
user里的public修饰的方法:public void org.example.reflect.entity.User.setAge(int)
user突破限制获取的方法:private void org.example.reflect.entity.User.say()
User{name='null', age=20, xb='null', dh='18943130289'}
我是user私有的方法
泛型java.util.Map<java.lang.String, java.lang.Integer>
interface java.util.Map
方法中的泛型:java.util.Map<java.lang.String, java.lang.Integer>
标签:反射,java,entity,reflect,public,User,example
From: https://www.cnblogs.com/mxkgmn/p/16627335.html