当前位置 : 主页 > 编程语言 > java >

Java--反射详解

来源:互联网 收集:自由互联 发布时间:2022-07-22
Java--反射详解 ​​动态语言​​ ​​反射机制--运行中知道全部的类和属性​​ ​​反射API​​ ​​Class​​ ​​Field​​ ​​Method​​ ​​Constructor​​ ​​反射步骤​​ ​​获


Java--反射详解

  • ​​动态语言​​
  • ​​反射机制--运行中知道全部的类和属性​​
  • ​​反射API​​
  • ​​Class​​
  • ​​Field​​
  • ​​Method​​
  • ​​Constructor​​
  • ​​反射步骤​​
  • ​​获取Class​​
  • ​​==getClass()==​​
  • ​​==class关键字==​​
  • ​​==forName()==​​
  • ​​获取实例对象​​
  • ​​==Class的newInstance()==​​
  • ​​==Constructor的newInstance()==​​

动态语言

动态语言,是指程序在运行时可以改变其结构:新的函数可以引进,已有的函数可以被删除等结构上的变化。比如常见的 JavaScript 就是动态语言,除此之外 Ruby,Python 等也属于动态语言,而 C、C++则不属于动态语言。从反射角度说 JAVA 属于半动态语言。

反射机制–运行中知道全部的类和属性

在 Java 中的反射机制是指在运行状态中,对于任意一个类都能够知道这个类所有的属性和方法;并且对于任意一个对象,都能够调用它的任意一个方法;这种动态获取信息以及动态调用对象方法的功能成为 Java 语言的反射机制。

Java--反射详解_Java反射使用

反射API

反射API用来生成JVM中的类、接口或者对象的信息。

  • Class类:反射的核心类,可以获取类的属性,方法等信息。
  • Field类:表示类的成员变量,可以用来获取和设置类中的属性值。
  • Method类:表示类的方法,可以用来类中的方法信息,或者执行方法。
  • Constructor类:表示类的构造方法。

Class

准备一个类

import java.io.Serializable;
@Deprecated
public class People implements Serializable {

private String name;

private Integer age;

private String testPrivate;

public String testPublic;

protected String testProtected;

String testDefault;

public People(){

}

public String say(){
return name+age;
}


public String getName() {
return this.name;
}

public Integer getAge() {
return this.age;
}

public String getTestPrivate() {
return this.testPrivate;
}

public String getTestPublic() {
return this.testPublic;
}

public String getTestProtected() {
return this.testProtected;
}

public String getTestDefault() {
return this.testDefault;
}

public void setName(String name) {
this.name = name;
}

public void setAge(Integer age) {
this.age = age;
}

public void setTestPrivate(String testPrivate) {
this.testPrivate = testPrivate;
}

public void setTestPublic(String testPublic) {
this.testPublic = testPublic;
}

public void setTestProtected(String testProtected) {
this.testProtected = testProtected;
}

public void setTestDefault(String testDefault) {
this.testDefault = testDefault;
}
}

接下来获取这个类的属性和方法等信息

import com.study.studyreflect.bean.People;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
public class ClassMain {

public static void main(String[] args) throws ClassNotFoundException {
Class clazz1 = People.class;
People people = new People();
Class clazz2 = people.getClass();
Class clazz3 = Class.forName("com.study.studyreflect.bean.People");
System.out.println(clazz1);
System.out.println(clazz2);
System.out.println(clazz3);
Method[] methods = clazz1.getMethods();
System.out.println("--------------------class----------------------------");
Arrays.asList(methods).stream().forEach(x->
System.out.println("class: " + x.getClass()+",name: " + x.getName() + ",parameter: " + x.getParameters().toString()+",returnType: " + x.getReturnType()));
System.out.println("--------------------public field----------------------------");
Field[] fields = clazz1.getFields();
Arrays.asList(fields).stream().forEach(x->
System.out.println("class: " + x.getClass() + ",name: " + x.getName() + ",type: " + x.getType()));
System.out.println("--------------------all field----------------------------");
Field[] declaredFields = clazz1.getDeclaredFields();
Arrays.asList(declaredFields).stream().forEach(x->
System.out.println("class: " + x.getClass() + ",name: " + x.getName() + ",type: " + x.getType() + ",getDeclaringClass: " + x.getDeclaringClass()));
System.out.println("--------------------annotations----------------------------");
Annotation[] annotations = clazz1.getAnnotations();
Arrays.asList(annotations).stream().forEach(x->
System.out.println("class: " + x.getClass() + ",type: " + x.annotationType()));
System.out.println("--------------------interface----------------------------");
Class[] interfaces = clazz1.getInterfaces();
Arrays.asList(interfaces).stream().forEach(x->
System.out.println("class: " + x.getClass() + ",name: " + x.getName() + ",typeName: " + x.getTypeName()));
}

}

输出

F:\JDK\jdk\jdk8u111\bin\java.exe "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2020.1.2\lib\idea_rt.jar=60825:C:\Program Files\JetBrains\IntelliJ IDEA 2020.1.2\bin" -Dfile.encoding=UTF-8 -classpath F:\JDK\jdk\jdk8u111\jre\lib\charsets.jar;F:\JDK\jdk\jdk8u111\jre\lib\deploy.jar;F:\JDK\jdk\jdk8u111\jre\lib\ext\access-bridge-64.jar;F:\JDK\jdk\jdk8u111\jre\lib\ext\cldrdata.jar;F:\JDK\jdk\jdk8u111\jre\lib\ext\dnsns.jar;F:\JDK\jdk\jdk8u111\jre\lib\ext\jaccess.jar;F:\JDK\jdk\jdk8u111\jre\lib\ext\jfxrt.jar;F:\JDK\jdk\jdk8u111\jre\lib\ext\localedata.jar;F:\JDK\jdk\jdk8u111\jre\lib\ext\nashorn.jar;F:\JDK\jdk\jdk8u111\jre\lib\ext\sunec.jar;F:\JDK\jdk\jdk8u111\jre\lib\ext\sunjce_provider.jar;F:\JDK\jdk\jdk8u111\jre\lib\ext\sunmscapi.jar;F:\JDK\jdk\jdk8u111\jre\lib\ext\sunpkcs11.jar;F:\JDK\jdk\jdk8u111\jre\lib\ext\zipfs.jar;F:\JDK\jdk\jdk8u111\jre\lib\javaws.jar;F:\JDK\jdk\jdk8u111\jre\lib\jce.jar;F:\JDK\jdk\jdk8u111\jre\lib\jfr.jar;F:\JDK\jdk\jdk8u111\jre\lib\jfxswt.jar;F:\JDK\jdk\jdk8u111\jre\lib\jsse.jar;F:\JDK\jdk\jdk8u111\jre\lib\management-agent.jar;F:\JDK\jdk\jdk8u111\jre\lib\plugin.jar;F:\JDK\jdk\jdk8u111\jre\lib\resources.jar;F:\JDK\jdk\jdk8u111\jre\lib\rt.jar;G:\studyjdk\out\production\studyreflect com.study.studyreflect.ClassMain
class com.study.studyreflect.bean.People
class com.study.studyreflect.bean.People
class com.study.studyreflect.bean.People
--------------------class----------------------------
class: class java.lang.reflect.Method,name: getName,parameter: [Ljava.lang.reflect.Parameter;@214c265e,returnType: class java.lang.String
class: class java.lang.reflect.Method,name: setName,parameter: [Ljava.lang.reflect.Parameter;@448139f0,returnType: void
class: class java.lang.reflect.Method,name: getAge,parameter: [Ljava.lang.reflect.Parameter;@7cca494b,returnType: class java.lang.Integer
class: class java.lang.reflect.Method,name: say,parameter: [Ljava.lang.reflect.Parameter;@7ba4f24f,returnType: class java.lang.String
class: class java.lang.reflect.Method,name: getTestPublic,parameter: [Ljava.lang.reflect.Parameter;@3b9a45b3,returnType: class java.lang.String
class: class java.lang.reflect.Method,name: setAge,parameter: [Ljava.lang.reflect.Parameter;@7699a589,returnType: void
class: class java.lang.reflect.Method,name: setTestPublic,parameter: [Ljava.lang.reflect.Parameter;@58372a00,returnType: void
class: class java.lang.reflect.Method,name: getTestPrivate,parameter: [Ljava.lang.reflect.Parameter;@4dd8dc3,returnType: class java.lang.String
class: class java.lang.reflect.Method,name: setTestDefault,parameter: [Ljava.lang.reflect.Parameter;@6d03e736,returnType: void
class: class java.lang.reflect.Method,name: setTestProtected,parameter: [Ljava.lang.reflect.Parameter;@568db2f2,returnType: void
class: class java.lang.reflect.Method,name: getTestProtected,parameter: [Ljava.lang.reflect.Parameter;@378bf509,returnType: class java.lang.String
class: class java.lang.reflect.Method,name: getTestDefault,parameter: [Ljava.lang.reflect.Parameter;@5fd0d5ae,returnType: class java.lang.String
class: class java.lang.reflect.Method,name: setTestPrivate,parameter: [Ljava.lang.reflect.Parameter;@2d98a335,returnType: void
class: class java.lang.reflect.Method,name: wait,parameter: [Ljava.lang.reflect.Parameter;@16b98e56,returnType: void
class: class java.lang.reflect.Method,name: wait,parameter: [Ljava.lang.reflect.Parameter;@7ef20235,returnType: void
class: class java.lang.reflect.Method,name: wait,parameter: [Ljava.lang.reflect.Parameter;@27d6c5e0,returnType: void
class: class java.lang.reflect.Method,name: equals,parameter: [Ljava.lang.reflect.Parameter;@4f3f5b24,returnType: boolean
class: class java.lang.reflect.Method,name: toString,parameter: [Ljava.lang.reflect.Parameter;@15aeb7ab,returnType: class java.lang.String
class: class java.lang.reflect.Method,name: hashCode,parameter: [Ljava.lang.reflect.Parameter;@7b23ec81,returnType: int
class: class java.lang.reflect.Method,name: getClass,parameter: [Ljava.lang.reflect.Parameter;@6acbcfc0,returnType: class java.lang.Class
class: class java.lang.reflect.Method,name: notify,parameter: [Ljava.lang.reflect.Parameter;@5f184fc6,returnType: void
class: class java.lang.reflect.Method,name: notifyAll,parameter: [Ljava.lang.reflect.Parameter;@3feba861,returnType: void
--------------------public field----------------------------
class: class java.lang.reflect.Field,name: testPublic,type: class java.lang.String
--------------------all field----------------------------
class: class java.lang.reflect.Field,name: name,type: class java.lang.String,getDeclaringClass: class com.study.studyreflect.bean.People
class: class java.lang.reflect.Field,name: age,type: class java.lang.Integer,getDeclaringClass: class com.study.studyreflect.bean.People
class: class java.lang.reflect.Field,name: testPrivate,type: class java.lang.String,getDeclaringClass: class com.study.studyreflect.bean.People
class: class java.lang.reflect.Field,name: testPublic,type: class java.lang.String,getDeclaringClass: class com.study.studyreflect.bean.People
class: class java.lang.reflect.Field,name: testProtected,type: class java.lang.String,getDeclaringClass: class com.study.studyreflect.bean.People
class: class java.lang.reflect.Field,name: testDefault,type: class java.lang.String,getDeclaringClass: class com.study.studyreflect.bean.People
--------------------annotations----------------------------
class: class com.sun.proxy.$Proxy1,type: interface java.lang.Deprecated
--------------------interface----------------------------
class: class java.lang.Class,name: java.io.Serializable,typeName: java.io.Serializable

Process finished with exit code 0

Field

还是使用People作为目标类,尝试用反射设置属性。

People新增基本类型的属性:

Java--反射详解_Java反射原理_02

注释掉全部的setter、getter方法

Java--反射详解_Java反射实例_03

重写toString方法

Java--反射详解_Java反射使用_04

接着使用反射设置属性:基本属性需要使用对应的setXXX方法

public class FieldMain {

public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
People people = new People();
Class clazz = Class.forName("com.study.studyreflect.bean.People");
System.out.println("------------setName----------------");
Field name = clazz.getDeclaredField("name");
name.setAccessible(true);
name.set(people, "小美");
System.out.println("------------setAge-----------------");
Field age = clazz.getDeclaredField("age");
age.setAccessible(true);
age.set(people, 22);
System.out.println("------------setNumber-----------------");
Field number = clazz.getDeclaredField("number");
number.setAccessible(true);
number.setInt(people, 88);
System.out.println("------------testPublic-----------------");
Field testPublic = clazz.getDeclaredField("testPublic");
testPublic.setAccessible(true);
testPublic.set(people,"test##public");
System.out.println("------------testprivate-----------------");
Field testPrivate = clazz.getDeclaredField("testPrivate");
testPrivate.setAccessible(true);
testPrivate.set(people,"test##private");
System.out.println("------------testProtected-----------------");
Field testProtected = clazz.getDeclaredField("testProtected");
testProtected.setAccessible(true);
testProtected.set(people, "test##protected");
System.out.println("------------testDefault-----------------");
Field testDefault = clazz.getDeclaredField("testDefault");
testDefault.setAccessible(true);
testDefault.set(people, "test##Default");
System.out.println(people);
}

}

输出结果

F:\JDK\jdk\jdk8u111\bin\java.exe "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2020.1.2\lib\idea_rt.jar=62716:C:\Program Files\JetBrains\IntelliJ IDEA 2020.1.2\bin" -Dfile.encoding=UTF-8 -classpath F:\JDK\jdk\jdk8u111\jre\lib\charsets.jar;F:\JDK\jdk\jdk8u111\jre\lib\deploy.jar;F:\JDK\jdk\jdk8u111\jre\lib\ext\access-bridge-64.jar;F:\JDK\jdk\jdk8u111\jre\lib\ext\cldrdata.jar;F:\JDK\jdk\jdk8u111\jre\lib\ext\dnsns.jar;F:\JDK\jdk\jdk8u111\jre\lib\ext\jaccess.jar;F:\JDK\jdk\jdk8u111\jre\lib\ext\jfxrt.jar;F:\JDK\jdk\jdk8u111\jre\lib\ext\localedata.jar;F:\JDK\jdk\jdk8u111\jre\lib\ext\nashorn.jar;F:\JDK\jdk\jdk8u111\jre\lib\ext\sunec.jar;F:\JDK\jdk\jdk8u111\jre\lib\ext\sunjce_provider.jar;F:\JDK\jdk\jdk8u111\jre\lib\ext\sunmscapi.jar;F:\JDK\jdk\jdk8u111\jre\lib\ext\sunpkcs11.jar;F:\JDK\jdk\jdk8u111\jre\lib\ext\zipfs.jar;F:\JDK\jdk\jdk8u111\jre\lib\javaws.jar;F:\JDK\jdk\jdk8u111\jre\lib\jce.jar;F:\JDK\jdk\jdk8u111\jre\lib\jfr.jar;F:\JDK\jdk\jdk8u111\jre\lib\jfxswt.jar;F:\JDK\jdk\jdk8u111\jre\lib\jsse.jar;F:\JDK\jdk\jdk8u111\jre\lib\management-agent.jar;F:\JDK\jdk\jdk8u111\jre\lib\plugin.jar;F:\JDK\jdk\jdk8u111\jre\lib\resources.jar;F:\JDK\jdk\jdk8u111\jre\lib\rt.jar;G:\studyjdk\out\production\studyreflect com.study.studyreflect.FieldMain
------------setName----------------
------------setAge-----------------
------------setNumber-----------------
------------testPublic-----------------
------------testprivate-----------------
------------testProtected-----------------
------------testDefault-----------------
People[name=小美,age=22,number=88,testPublic=test##public,testPrivate=test##private,testProtected=test##protected,testDefault=test##Default]

Process finished with exit code 0

这反射就是个bug,完全不理会权限…

小例子,使用反射,创建20个实例,名字+id

public class FieldMain {

public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException {
Class clazz = Class.forName("com.study.studyreflect.bean.People");
int summer = 10;
Object[] objects = new Object[summer];
for (int i = 0; i < summer; i++) {
Object instance = clazz.newInstance();
Field name = clazz.getDeclaredField("name");
name.setAccessible(true);
name.set(instance, "小美"+i);
objects[i] = instance;
}
Arrays.asList(objects).stream().forEach(System.out::println);
}

}

结果:

Java--反射详解_Java反射实例_05

Method

新增不同权限的方法:

Java--反射详解_体验Java反射_06

接下来使用反射执行这些方法

import com.study.studyreflect.bean.People;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class MethodMain {

public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
Class clazz = Class.forName("com.study.studyreflect.bean.People");
People people = (People) clazz.newInstance();
people.setName("小美");
people.setAge(24);
people.setNumber(78);
System.out.println("-------------------public------------");
Method sayPublic = clazz.getDeclaredMethod("say", null);
sayPublic.setAccessible(true);
System.out.println("public: " + sayPublic.invoke(people, null));
System.out.println("-------------------private------------");
Method sayPrivate = clazz.getDeclaredMethod("say", String.class);
sayPrivate.setAccessible(true);
System.out.println("private: " + sayPrivate.invoke(people, "小美:private"));
System.out.println("-------------------protected------------");
Method sayProtected = clazz.getDeclaredMethod("say", Integer.class);
sayProtected.setAccessible(true);
System.out.println("protected: " + sayProtected.invoke(people, 244));
System.out.println("-------------------default------------");
Method sayDefault = clazz.getDeclaredMethod("say", Double.class);
sayDefault.setAccessible(true);
System.out.println("default: " + sayDefault.invoke(people, 24.444));
System.out.println("-------------------toString------------");
Method toString = clazz.getDeclaredMethod("toString", null);
toString.setAccessible(true);
System.out.println("toString: " + toString.invoke(people, null));
}

}

执行结果

F:\JDK\jdk\jdk8u111\bin\java.exe "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2020.1.2\lib\idea_rt.jar=64218:C:\Program Files\JetBrains\IntelliJ IDEA 2020.1.2\bin" -Dfile.encoding=UTF-8 -classpath F:\JDK\jdk\jdk8u111\jre\lib\charsets.jar;F:\JDK\jdk\jdk8u111\jre\lib\deploy.jar;F:\JDK\jdk\jdk8u111\jre\lib\ext\access-bridge-64.jar;F:\JDK\jdk\jdk8u111\jre\lib\ext\cldrdata.jar;F:\JDK\jdk\jdk8u111\jre\lib\ext\dnsns.jar;F:\JDK\jdk\jdk8u111\jre\lib\ext\jaccess.jar;F:\JDK\jdk\jdk8u111\jre\lib\ext\jfxrt.jar;F:\JDK\jdk\jdk8u111\jre\lib\ext\localedata.jar;F:\JDK\jdk\jdk8u111\jre\lib\ext\nashorn.jar;F:\JDK\jdk\jdk8u111\jre\lib\ext\sunec.jar;F:\JDK\jdk\jdk8u111\jre\lib\ext\sunjce_provider.jar;F:\JDK\jdk\jdk8u111\jre\lib\ext\sunmscapi.jar;F:\JDK\jdk\jdk8u111\jre\lib\ext\sunpkcs11.jar;F:\JDK\jdk\jdk8u111\jre\lib\ext\zipfs.jar;F:\JDK\jdk\jdk8u111\jre\lib\javaws.jar;F:\JDK\jdk\jdk8u111\jre\lib\jce.jar;F:\JDK\jdk\jdk8u111\jre\lib\jfr.jar;F:\JDK\jdk\jdk8u111\jre\lib\jfxswt.jar;F:\JDK\jdk\jdk8u111\jre\lib\jsse.jar;F:\JDK\jdk\jdk8u111\jre\lib\management-agent.jar;F:\JDK\jdk\jdk8u111\jre\lib\plugin.jar;F:\JDK\jdk\jdk8u111\jre\lib\resources.jar;F:\JDK\jdk\jdk8u111\jre\lib\rt.jar;G:\studyjdk\out\production\studyreflect com.study.studyreflect.MethodMain
-------------------public------------
public: 小美24
-------------------private------------
private: 小美:private
-------------------protected------------
protected: 244
-------------------default------------
default: 24.444
-------------------toString------------
toString: People[name=小美,age=24,number=78,testPublic=null,testPrivate=null,testProtected=null,testDefault=null]

Process finished with exit code 0

果真是个bug…

这里一定程度上能够体现:为什么java重载方法,不能根据权限和返回值区分,因为在反射中,相同名字的方法的唯一区分方式就是参数类型或者参数个数。

所以,重载方法,一定是参数不同。

Constructor

People有两个构造方法

Java--反射详解_Java反射原理_07

接着使用反射试试

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class ConstructorMain {

public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
Class clazz = Class.forName("com.study.studyreflect.bean.People");
Constructor defaultCon = clazz.getDeclaredConstructor(null);
defaultCon.setAccessible(true);
Object defaultInstance = defaultCon.newInstance(null);
System.out.println(defaultInstance);
Constructor stringCon = clazz.getDeclaredConstructor(String.class);
stringCon.setAccessible(true);
Object xiao = stringCon.newInstance("小丽");
System.out.println(xiao);
}

}

执行结果

F:\JDK\jdk\jdk8u111\bin\java.exe "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2020.1.2\lib\idea_rt.jar=64841:C:\Program Files\JetBrains\IntelliJ IDEA 2020.1.2\bin" -Dfile.encoding=UTF-8 -classpath F:\JDK\jdk\jdk8u111\jre\lib\charsets.jar;F:\JDK\jdk\jdk8u111\jre\lib\deploy.jar;F:\JDK\jdk\jdk8u111\jre\lib\ext\access-bridge-64.jar;F:\JDK\jdk\jdk8u111\jre\lib\ext\cldrdata.jar;F:\JDK\jdk\jdk8u111\jre\lib\ext\dnsns.jar;F:\JDK\jdk\jdk8u111\jre\lib\ext\jaccess.jar;F:\JDK\jdk\jdk8u111\jre\lib\ext\jfxrt.jar;F:\JDK\jdk\jdk8u111\jre\lib\ext\localedata.jar;F:\JDK\jdk\jdk8u111\jre\lib\ext\nashorn.jar;F:\JDK\jdk\jdk8u111\jre\lib\ext\sunec.jar;F:\JDK\jdk\jdk8u111\jre\lib\ext\sunjce_provider.jar;F:\JDK\jdk\jdk8u111\jre\lib\ext\sunmscapi.jar;F:\JDK\jdk\jdk8u111\jre\lib\ext\sunpkcs11.jar;F:\JDK\jdk\jdk8u111\jre\lib\ext\zipfs.jar;F:\JDK\jdk\jdk8u111\jre\lib\javaws.jar;F:\JDK\jdk\jdk8u111\jre\lib\jce.jar;F:\JDK\jdk\jdk8u111\jre\lib\jfr.jar;F:\JDK\jdk\jdk8u111\jre\lib\jfxswt.jar;F:\JDK\jdk\jdk8u111\jre\lib\jsse.jar;F:\JDK\jdk\jdk8u111\jre\lib\management-agent.jar;F:\JDK\jdk\jdk8u111\jre\lib\plugin.jar;F:\JDK\jdk\jdk8u111\jre\lib\resources.jar;F:\JDK\jdk\jdk8u111\jre\lib\rt.jar;G:\studyjdk\out\production\studyreflect com.study.studyreflect.ConstructorMain
People[name=null,age=null,number=0,testPublic=null,testPrivate=null,testProtected=null,testDefault=null]
People[name=小丽,age=null,number=0,testPublic=null,testPrivate=null,testProtected=null,testDefault=null]

Process finished with exit code 0

反射步骤

  • 获取Class对象
  • 获取Class方法或者属性
  • 执行Class方法或者属性赋值
  • 获取Class

    getClass()

    Object object = new Object();
    Class clazz = object.getClass();

    class关键字

    Class clazz = Object.class;

    forName()

    Class clazz = Class.forName("com.xxxxxx");

    获取实例对象

    Class的newInstance()

    Java--反射详解_Java反射实例_08

    Constructor的newInstance()

    Java--反射详解_Java反射使用_09


    网友评论