[TOC]
java反射
个人理解
在运行状态中,对于任何一个类,都能获取到这个类的所有信息,例如该类中的方法,属性,及实现的接口等等;并且还能调用该类的任一方法或属性;这种在运行时动态的获取类信息或调用类中的属性或方法称之为反射
实战
所用到的实体类
这个类是我直接复制的,就没有去自己写了,自己在toString
方法上添加了@Override
注解,本来是准备写下注解的方法的,结果代码太多,就没写。
@Resourcepublic class Reflection implements Cloneable, Serializable { private String str; private double d; public boolean b; public static short s; public Reflection() { } public Reflection(String str) { this.str = str; } public Reflection(String str, double d, boolean b) { this.str = str; this.d = d; this.b = b; } private void privateMethod() { } public String publicMethod() { privateMethod(); return null; } public String publicMethod(int i) { return null; } public String publicMethod(int i, double d, Listl) { return "Reflection.publicMethod(int i, double d), i = " + i + ", d = " + d; } public static int returnOne() { return 1; } @Override public String toString() { return "str = " + str + ", d = " + d + ", b = " + b; } }复制代码
class
class的一些信息
- 获取class的中方法
//1 Class aClass = Class.forName("com.example.demo.reflex.one.Reflection"); //2 Class aClass1 = new Reflection().getClass(); //3 ClassreflectionClass = Reflection.class;复制代码
- 对类信息操作 代码
@Test public void classTest() throws ClassNotFoundException { Class aClass = Class.forName("com.example.demo.reflex.one.Reflection"); System.out.println("获取该类的父类: "+aClass.getSuperclass()); System.out.println("获取java.lang.Class的Class对象: "+aClass.getClass()); System.out.println("获取类的加载器: "+aClass.getClassLoader()); System.out.println("获取该类的注解: "+aClass.getAnnotations()[0]); //注意返回的是数组;}复制代码
运行结果:
获取该类的父类: class java.lang.Object获取java.lang.Class的Class对象: class java.lang.Class获取类的加载器: sun.misc.Launcher$AppClassLoader@18b4aac2获取该类的注解: @javax.annotation.Resource(shareable=true, lookup=, name=, description=, authenticationType=CONTAINER, type=class java.lang.Object, mappedName=)复制代码
Field
对属性操作
- 代码
@Test public void fieldTest() throws ClassNotFoundException, NoSuchFieldException { Class aClass = Class.forName("com.example.demo.reflex.one.Reflection"); Field f0 = aClass.getField("b"); System.out.println("aClass.getField(String name)通过名字获取该类中访问权限为public的字段"+f0); System.out.println(); Field f1 =aClass.getDeclaredField("d"); System.out.println("aClass.getDeclaredField(String name)通过名字获取该类中任意访问权限的字段"+f1); System.out.println(); Field[] fields = aClass.getFields(); System.out.println("aClass.getFields()是获取该类中所有public字段,包括继承而来的public字段"); for(Field field:fields){ System.out.println(field); } System.out.println(); Field[] declaredFields = aClass.getDeclaredFields(); System.out.println("aClass.getDeclaredFields()是获取该类中所有字段,不限制访问权限,不包括继承而来的"); for(Field field:declaredFields){ System.out.println(field); } System.out.println(); System.out.println("获取字段名字:Field.getName():" + f0.getName()); System.out.println("获取字段类型:Field.getType():" + f0.getType()); System.out.println("以整数形式返回此Field对象的Java语言修饰符:Field.getModifiers():" + f0.getModifiers()); System.out.println("使用Modifier解析后的修饰符:"+Modifier.toString(f0.getModifiers())); 返回Field的访问权限,对private的Field赋值,必须要将accessible设置为true System.out.println("Field.isAccessible():" + f0.isAccessible()); }复制代码
- 运行结果
aClass.getField(String name)通过名字获取该类中访问权限为public的字段public boolean com.example.demo.reflex.one.Reflection.baClass.getDeclaredField(String name)通过名字获取该类中任意访问权限的字段private double com.example.demo.reflex.one.Reflection.daClass.getFields()是获取该类中所有public字段,包括继承而来的public字段public boolean com.example.demo.reflex.one.Reflection.bpublic static short com.example.demo.reflex.one.Reflection.saClass.getDeclaredFields()是获取该类中所有字段,不限制访问权限,不包括继承而来的private java.lang.String com.example.demo.reflex.one.Reflection.strprivate double com.example.demo.reflex.one.Reflection.dpublic boolean com.example.demo.reflex.one.Reflection.bpublic static short com.example.demo.reflex.one.Reflection.s获取字段名字:Field.getName():b获取字段类型:Field.getType():boolean以整数形式返回此Field对象的Java语言修饰符:Field.getModifiers():1使用Modifier解析后的修饰符:publicField.isAccessible():false复制代码
method
对方法进行操作
- 代码
@Test public void getMethod() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException { Class aClass = Class.forName("com.example.demo.reflex.one.Reflection"); Method publicMethod = aClass.getMethod("publicMethod", int.class, double.class, List.class); System.out.println("根据方法名字和参数获取方法,包括继承而来的public方法:Class.getMethod:"+publicMethod); System.out.println(); Method toString = aClass.getDeclaredMethod("toString"); System.out.println("根据方法名获取本类方法,包括私有的:Class.getDeclaredMethod:"+toString); System.out.println(); Method[] methods = aClass.getMethods(); System.out.println("该类的所有方法,包括继承父类而来的public方法"); for(Method m:methods){ System.out.println(m); } System.out.println(); Method[] declaredMethods = aClass.getDeclaredMethods(); System.out.println("本类声明的所有方法,不包括继承父类而来的方法"); for(Method m:declaredMethods){ System.out.println(m); } System.out.println(); Class [] parameterTypes = publicMethod.getParameterTypes(); System.out.println("获取该方法的参数:Method.getParameterTypes"); for (Class c:parameterTypes){ System.out.println(c); } System.out.println(); System.out.println("获取方法的名字:Method.getName():"+publicMethod.getName()); System.out.println(" 获取方法的访问属性:Method.isAccessible():"+publicMethod.isAccessible()); System.out.println(" 获取方法的返回类型:Method.getReturnType():"+publicMethod.getReturnType()); System.out.println("反射调用方法"+publicMethod.invoke(aClass.newInstance(),1,2.3,new ArrayList())); }复制代码
- 运行结果
根据方法名字和参数获取方法,包括继承而来的public方法:Class.getMethod:public java.lang.String com.example.demo.reflex.one.Reflection.publicMethod(int,double,java.util.List)根据方法名获取本类方法,包括私有的:Class.getDeclaredMethod:public java.lang.String com.example.demo.reflex.one.Reflection.toString()该类的所有方法,包括继承父类而来的public方法public java.lang.String com.example.demo.reflex.one.Reflection.toString()public java.lang.String com.example.demo.reflex.one.Reflection.publicMethod()public java.lang.String com.example.demo.reflex.one.Reflection.publicMethod(int)public java.lang.String com.example.demo.reflex.one.Reflection.publicMethod(int,double,java.util.List)public static int com.example.demo.reflex.one.Reflection.returnOne()public final void java.lang.Object.wait() throws java.lang.InterruptedExceptionpublic final void java.lang.Object.wait(long,int) throws java.lang.InterruptedExceptionpublic final native void java.lang.Object.wait(long) throws java.lang.InterruptedExceptionpublic 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 com.example.demo.reflex.one.Reflection.toString()public java.lang.String com.example.demo.reflex.one.Reflection.publicMethod()public java.lang.String com.example.demo.reflex.one.Reflection.publicMethod(int)public java.lang.String com.example.demo.reflex.one.Reflection.publicMethod(int,double,java.util.List)private void com.example.demo.reflex.one.Reflection.privateMethod()public static int com.example.demo.reflex.one.Reflection.returnOne()获取该方法的参数:Method.getParameterTypesintdoubleinterface java.util.List获取方法的名字:Method.getName():publicMethod 获取方法的访问属性:Method.isAccessible():false 获取方法的返回类型:Method.getReturnType():class java.lang.String反射调用方法Reflection.publicMethod(int i, double d), i = 1, d = 2.3复制代码
Constructor
- 代码
@Test public void constructorTest() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { Class aClass = Class.forName("com.example.demo.reflex.one.Reflection"); Constructor [] constructors = aClass.getConstructors(); System.out.println("获取所有的构造方法:Class.getConstructors:"); for(Constructor c:constructors){ System.out.println(c); } System.out.println(); Constructor constructor = aClass.getConstructor(String.class); System.out.println("Class.getConstructor(T.class):指定参数顺序来获取构造函数:"+constructor); System.out.println(); System.out.println("以整数形式返回方法对象的Java修饰符:constructor.getModifiers():"+constructor.getModifiers()); System.out.println(); System.out.println("Constructor.isAccessible():获取该Constructor的访问权限:"+constructor.isAccessible()); System.out.println(); Class [] parameterTypes = constructors[0].getParameterTypes(); System.out.println("Constructor.getParameterTypes():获取该方法的参数列表:"); for(Class param:parameterTypes){ System.out.println(param); } System.out.println(); System.out.println("Constructor.isVarArgs():判断该方法是否带了可变数量的参数:" + constructor.isVarArgs()); System.out.println(); System.out.println("实例化"); // 根据指定的构造方法实例化出一个类的实例来,重要 Reflection reflection = (Reflection) constructor.newInstance("测试"); System.out.println("Constructor.newInstance():" + reflection); }复制代码
- 运行结果
获取所有的构造方法:Class.getConstructors:public com.example.demo.reflex.one.Reflection(java.lang.String,double,boolean)public com.example.demo.reflex.one.Reflection(java.lang.String)public com.example.demo.reflex.one.Reflection()Class.getConstructor(T.class):指定参数顺序来获取构造函数:public com.example.demo.reflex.one.Reflection(java.lang.String)以整数形式返回方法对象的Java修饰符:constructor.getModifiers():1Constructor.isAccessible():获取该Constructor的访问权限:falseConstructor.getParameterTypes():获取该方法的参数列表:class java.lang.StringdoublebooleanConstructor.isVarArgs():判断该方法是否带了可变数量的参数:false实例化Constructor.newInstance():str = 测试, d = 0.0, b = false复制代码
Modifier枚举值列表
Field、Constructor、Method中都有getModifiers()方法,返回的是表示此对象的Java语言修饰符,详细看下每个修饰符对应的枚举值:
修饰符 | 枚举值 |
---|---|
public | 1 |
private | 2 |
protected | 4 |
static | 8 |
final | 16 |
synchronized | 32 |
volatile | 64 |
transient | 128 |
native | 256 |
interface | 512 |
abstract | 1024 |
strict | 2048 |
可以调用Modifier.toString()
来解析这个值,直接输出修饰符
总结
- 自己对反射的理论知识还很差,需要多看书;
- 我上边的代码其实只是反射中很少的一部分,写这么多代码知识想说明自己去学过,至少自己copy都代表动了手的,总比没动手好;
- 反射这个东西是个好东西,我只是学到了皮毛,需要学的东西还有很多很多;
- 其实平时接触的技术中很多都用到了反射,只是自己暂时还没有那个能力去看而已,总有一天会看到的;
- 在这里十分感谢,我是看了他写的文章才写出来的这篇文章;当然,你也可以认为我是复制的他的文章;