Java Reflection
2018-10-09 本文已影响0人
ZozoSpider
类
类的实例对象
如何创建类的实例对象?
- 直接new
- 通过class实例化(需要有无参数的构造方法)
CLass类的实例对象
类本身也是一个实例对象,任何类都是Class类的实例对象。
如何创建Class类都实例对象?
- 任何一个类都有一个隐含的静态成员变量class
- 通过该类对象的getClass方法
- Class.forName
public class ClassDemo1 {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
// Foo类的实例对象 方式1
// 直接new
Foo foo1 = new Foo();
foo1.func();
// Foo类本身也是一个实例对象,是Class类的实例对象,任何类都是Class类的实例对象,这个实例对象有三种表示方式如下
// CLass类的实例对象 方式1
// 任何一个类都有一个隐含的静态成员变量class
Class clazz1 = Foo.class;
// CLass类的实例对象 方式2
// 通过该类对象的getClass方法
Class clazz2 = foo1.getClass();
// CLass类的实例对象 方式3
// Class.forName
Class clazz3 = Class.forName("reflection.ClassDemo1");
// 官网clazz1, clazz2, clazz3表示了Foo类的类类型(Class type),不管clazz1, clazz2, clazz3都代表了Foo类的类类型,一个类只可能是Class类的一个实例对象
System.out.println(clazz1 == clazz2 && clazz1 == clazz3); // True
// Foo类的实例对象 方式2
// 通过class实例化(需要有无参数的构造方法)
Foo foo2 = (Foo) clazz1.newInstance();
foo2.func();
}
}
class Foo {
void func() {
}
}
静态加载与动态加载
- 通过new,静态加载类,编译时加载所有可能用到的类
- 通过Class.forName,动态加载类,运行时加载用到的类
public interface Office {
void start();
}
public class Word implements Office {
public void start() {
System.out.println("Word start");
}
}
public class Excel implements Office {
public void start() {
System.out.println("Excel start");
}
}
public class OfficeUser1 {
public static void main(String[] args) {
// 通过new,静态加载类,编译时需要加载所有可能用到的类
if ("Word".equals(args[0])) {
Word word = new Word();
word.start();
}
if ("Excel".equals(args[0])) {
Excel excel = new Excel();
excel.start();
}
}
}
public class OfficeUser2 {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
// 运行时动态加载类
Class<?> clazz = Class.forName(args[0]);
// 通过类类型,创建该类对象
Office office = (Office) clazz.newInstance();
office.start();
}
}
常见类类型 & 运行结果
public class ClassDemo2 {
public static void main(String[] args) {
// 基本数据类型class type
Class clazz1 = int.class;
Class clazz2 = double.class;
// void返回类型class type
Class clazz3 = void.class;
Class clazz4 = Double.class;
Class clazz5 = String.class;
System.out.println(clazz1.getName());
System.out.println(clazz2.getName());
System.out.println(clazz3.getName());
System.out.println(clazz4.getName());
System.out.println(clazz5.getName());
System.out.println(clazz5.getSimpleName());
}
}
int
double
void
java.lang.Double
java.lang.String
String
解析Class的所有字段,方法,构造方法 & 运行结果
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class ClassUtil {
/**
* 解析Class的字段信息
* @param obj
*/
public static void printClassFields(Object obj) {
// 传递的是哪个子类的对象,就是该子类的类型
Class<?> clazz = obj.getClass();
System.out.println("printClassField---------类名称:" + clazz.getName());
// 获取所有public字段,包括父类
Field[] fields = clazz.getFields();
// 获取所有自己声明的字段,包括所有权限的
Field[] declaredFields = clazz.getDeclaredFields();
// 遍历所有字段
for (Field field : fields) {
// 成员变量类型的class type
Class<?> type = field.getType();
// 成员变量类型的名称
String typeName = type.getName();
System.out.print(typeName + " ");
// 成员的名称
String fieldName = field.getName();
System.out.println(fieldName);
}
}
/**
* 解析Class的方法信息
* @param obj
*/
public static void printClassMethods(Object obj) {
// 传递的是哪个子类的对象,就是该子类的类型
Class<?> clazz = obj.getClass();
System.out.println("printClassMethod---------类名称:" + clazz.getName());
// 获取所有public方法,包括父类
Method[] methods = clazz.getMethods();
// 获取所有自己声明的方法,包括所有权限的
Method[] declaredMethods = clazz.getDeclaredMethods();
// 遍历所有方法
for (Method method : methods) {
// 方法的返回值的class type
Class<?> returnType = method.getReturnType();
// 方法的返回值的名称
String returnTypeName = returnType.getName();
System.out.print(returnTypeName + " ");
// 方法的名称
String methodName = method.getName();
System.out.print(methodName + "(");
// 所有方法参数的class type
Class<?>[] parameterTypes = method.getParameterTypes();
for (Class<?> parameterType : parameterTypes) {
// 方法参数的名称
String parameterTypeName = parameterType.getName();
System.out.print(parameterTypeName + ", ");
}
System.out.println(")");
}
}
/**
* 解析Class的构造方法信息
* @param obj
*/
public static void printClassConstructors(Object obj) {
// 传递的是哪个子类的对象,就是该子类的类型
Class<?> clazz = obj.getClass();
System.out.println("printClassConstructors---------类名称:" + clazz.getName());
// 获取所有public构造方法,包括父类
Constructor<?>[] constructors = clazz.getConstructors();
// 获取所有自己声明的构造方法,包括所有权限的
Constructor<?>[] declaredConstructors = clazz.getDeclaredConstructors();
// 遍历所有构造方法
for (Constructor<?> constructor : constructors) {
// 构造方法的名称
String constructorName = constructor.getName();
System.out.println(constructorName + "(");
// 所有方法参数的class type
Class<?>[] parameterTypes = constructor.getParameterTypes();
for (Class<?> parameterType : parameterTypes) {
// 方法参数的名称
String parameterTypeName = parameterType.getName();
System.out.print(parameterTypeName + ", ");
}
System.out.println(")");
}
}
public static void main(String[] args) {
String s = "ss";
ClassUtil.printClassFields(s);
ClassUtil.printClassMethods(s);
ClassUtil.printClassConstructors(s);
System.out.println("------------------------------------------------");
Integer i = 1;
ClassUtil.printClassFields(i);
ClassUtil.printClassMethods(i);
ClassUtil.printClassConstructors(i);
}
}
printClassField---------类名称:java.lang.String
java.util.Comparator CASE_INSENSITIVE_ORDER
printClassMethod---------类名称:java.lang.String
boolean equals(java.lang.Object, )
java.lang.String toString()
int hashCode()
void getChars(int, int, [C, int, )
[B getBytes()
java.util.stream.IntStream codePoints()
...
printClassConstructors---------类名称:java.lang.String
java.lang.String(
[B, int, int, )
java.lang.String(
[B, java.nio.charset.Charset, )
java.lang.String(
[C, )
...
------------------------------------------------
printClassField---------类名称:java.lang.Integer
int MIN_VALUE
int MAX_VALUE
java.lang.Class TYPE
int SIZE
int BYTES
printClassMethod---------类名称:java.lang.Integer
int numberOfLeadingZeros(int, )
boolean equals(java.lang.Object, )
java.lang.String toString(int, int, )
int min(int, int, )
byte byteValue()
short shortValue()
java.lang.Integer getInteger(java.lang.String, java.lang.Integer, )
int compareUnsigned(int, int, )
void wait(long, int, )
void wait()
...
printClassConstructors---------类名称:java.lang.Integer
java.lang.Integer(
int, )
java.lang.Integer(
java.lang.String, )
方法的反射 & 运行结果
获取方法:方法的名称和方法的参数
执行方法:method.invoke(对象, 参数列表);
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class MethodDemo1 {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
// get class
C c = new C();
Class<? extends C> clazz = c.getClass();
// get method
Method method1b = clazz.getMethod("print", new Class[]{});
Method method1a = clazz.getMethod("print");
Method method2a = clazz.getMethod("print", new Class[]{String.class, String.class});
Method method2b = clazz.getMethod("print", String.class, String.class);
Method method3a = clazz.getMethod("print", new Class[]{int.class, int.class});
Method method3b = clazz.getMethod("print", int.class, int.class);
// invoke method
c.print();
Object return1a = method1a.invoke(c, new Object[]{});
Object return1b = method1a.invoke(c);
System.out.println("return1a: " + return1a);
System.out.println("return1b: " + return1b);
System.out.println("------------");
c.print("hi", "world");
Object return2a = method2a.invoke(c, new String[]{"hi", "world"});
Object return2b = method2a.invoke(c, "hi", "world");
System.out.println("return2a: " + return2a);
System.out.println("return2b: " + return2b);
System.out.println("------------");
c.print(10, 20);
Object return3a = method3a.invoke(c, new Object[]{10, 20});
Object return3b = method3a.invoke(c, 10, 20);
System.out.println("return3a: " + return3a);
System.out.println("return3b: " + return3b);
}
}
class C {
// method1
public void print() {
System.out.println("hello, world!");
}
// method2
public void print(String a, String b) {
System.out.println(a + ", " + b);
}
// method3
public int print(int a, int b) {
System.out.println(a + ", " + b);
return a + b;
}
}
hello, world!
hello, world!
hello, world!
return1a: null
return1b: null
------------
hi, world
hi, world
hi, world
return2a: null
return2b: null
------------
10, 20
10, 20
10, 20
return3a: 30
return3b: 30