Reflect Java反射机制
// 参考:http://blog.csdn.net/stevenhu_223/article/details/9286121
最近发现好多框架底层的实现与Java的reflect和cglib有关,看过原理后找了几篇经典的文档,以供后来复习使用
前言:我们知道,类和类的成员变量及方法都是要求有权限控制的(public、protected、private);而当类中的信息封装为私有时,外部对该类中私有的信息是没有访问权限的,也就是说当该类里的内容信息均受private权限控制时,外部想要获取和处理该类里的私有信息是几乎不可能的;但是,有时候这种需求是有的,而当我们非得需要去动用别的类里封装的私有信息时,java的反射机制就起到了非常关键的作用了;
java反射机制的实现主要由三个类来主导:它们分别是Class、Field、Method;
1. Class:
java在编译和运行时,会将需要被编译和运行的所有类加载进类加载器,每个类被加载之后,系统就会为该类生成一个对应的Class对象,通过该Class对象就可以访问到java虚拟机中的这个类,进而在运行时对这个被访问的类进行信息的获取和处理(当然,不管被访问的这个类里的信息是否私有的);通俗的讲,Class对象间接代表了它对应的类,通过这个Class对象,我们就可以去执行反射机制的实现;
获取Class对象主要有三种方式:
1). 调用Class类的forName(String name)静态方法,参数name为Class对应的类的全名(包括包名);
比如我们要创建Gesture这个类对应的Class对象:
Class<Gesture> mClass = Class.forName("android.gesture.Gesture");
android.gesture为Gesture的包名,Class<Gesture>中的Gesture表示得到的是Gesture类型对应的Class对象,<>中的Gesture也可为通配符?表示,如:Class<?>mClass = Class.forName("android.gesture.Gesture");
2). 调用类的class属性得到类对应的Class对象。如:Class<?>mClass = Gesture.class; (一般建议用这种方式得到Class对象)
3).调用类的实例化对象的getClass()方法。特别说明的是,getClass()是java类的始祖Object类的方法,所以,所有java对象都可以调用该方法;如mGesture是Gesture类型的对象,Class<?> mClass = mGesture.getClass()得到的是Gesture类对应的Class对象
那么在得到对应类的Class对象对应后,我们就可以通过该Class对象得到它所对应的类的一些信息,比如该类的构造函数、成员(属性)、方法(函数);
Class类提供的相关接口介绍:(详细参看API)
接口 | 返回类型 | 接口功能实现 |
getPackage() | Package | 得到目标类的包名对应的Package对象 |
getCanonicalName() | String | 得到目标类的全名(包名+类名) |
getName() | String | 同getCanonicalName() |
getClassLoader() | ClassLoader | 得到加载目标类的ClassLoader对象 |
getClasses() | Class<?>[] | 得到目标类中的所有的public内部类以及public内部接口所对应的Class对象 |
getDeclaredClasses() | Class<?>[] | 同getClasses(),但不局限于public修饰,只要是目标类中声明的内部类和接口均可 |
getConstructors() | Constructor<?>[] | 得到目标类的所有public构造函数对应的Constructor对象 |
getDeclaredConstructors() | Constructor<?>[] | 同getConstructors(),但不局限于public修饰,只要是目标类中声明的构造函数均可 |
getField(String arg) | Field | 得到目标类中指定的某个public属性对应的Field对象 |
getDeclaredField(String arg) | Field | 同getField,但不局限于public修饰,只要是目标类中声明的属性均可 |
getFields() | Field[] | 得到目标类中所有的public属性对应的Field对象 |
getDeclaredFields() | Field[] | 同getFields(),但不局限于public修饰的属性 |
getMethod(String arg0, Class<?>... arg1) | method | 得到目标类中指定的某个public方法对应的Method对象 |
getDeclaredMethod(String arg0, Class<?>... arg1) | Method | 同getMethod,但不局限于public修饰的方法 |
getMethods() | Method[] | 得到目标类中所有的public方法对应的Method对象 |
getDeclaredMethods() | Method[] | 同getMethods(),但不局限于public修饰的方法 |
getEnclosingClass() | Class | 得到目标类所在的外围类的Class对象 |
getGenericInterfaces() | Type[] | 得到目标类实现的接口对应的Type对象 |
getGenericSuperclass() | Type | 得到目标类继承的父类所对应的Type对象 |
getInterfaces() | Class<?>[] | 得到目标类实现的接口所对应的Class对象 |
getSuperclass() | Class | 得到目标类继承的父类所对应的Class对象 |
isMemberClass() | boolean | 目标类是否为成员类 |
cisAnonymousClass() | boolean | 目标类是否为匿名类 |
2.Field:
我们知道一般类里包含有属性(成员)和方法(函数),竟然Class是描述类的信息,那么类其它部分应该会对应有描述它们的部分,而Field类型的对象就是描述Class对象对应类的出现包括public、protected、private属性);一个Field对象对应描述一个类的属性;
通过上文对Class的介绍,我们知道Class提供了四种接口函数可以得到对应属性的Field:
1). getField(String name):返回类型为Field,name为类中的属性名,得到的是描述类中的一个public属性对应的Field对象;如 Field mField =mClass.getField("mGestureID") 得到的是Gesture类中的一个public属性mGestureID对应的Field对象;
2). getFields():返回类型为Field类型数组,得到的是描述类中的所有public属性对应的所有Field对象;
3). getDeclaredField(String name):同getField(String name),只不过得到的Field对象描述的不只是public属性,
还包括protected、private属性,也是说只要是在类中声明的属性;
4). getDeclaredFields():getFields(),得到的是描述类中声明的所有属性(public、protected、private)对应的Field对象;
Field类的相关函数接口介绍:
Field类提供的相关接口介绍:(详细参看API)
接口 | 返回类型 | 接口功能实现 |
setAccessible(boolean flag) | void | 参数为true,只要是在类中声明的目标属性均可访问,为false,只有public目标属性可访问 |
set(Object object, Object value) | void | 给目标属性设置值(private、protected属性均不能访问,但可以通过先调用setAccessible(true)实现访问),第一个参数为目标属性所在类的对象,第二个参数为传入的值 |
get(Object object) | Object | 得到目标属性的值(private、protected属性均不能访问,但可以通过调用setAccessible(true)实现访问),参数为目标属性所在类的对象 |
setBoolean(Object object, boolean value) | void | 同set(Object object, Object value),只不过操作的数据类型为boolean |
getBoolean(Object object) | boolean | 同get(Object object),只不过得到的数据类型为boolean |
setByte(Object object, boolean value) | void | 同set(Object object, Object value),只不过操作的数据类型为byte |
getByte(Object object) | byte | 同get(Object object),只不过得到的数据类型为byte |
setShort(Object object, boolean value) | void | 同set(Object object, Object value),只不过操作的数据类型为short |
getShort(Object object) | short | 同get(Object object),只不过得到的数据类型为short |
setInt(Object object, boolean value) | void | 同set(Object object, Object value),只不过操作的数据类型为int |
getInt(Object object) | int | 同get(Object object),只不过得到的数据类型为int |
setLong(Object object, boolean value) | void | 同set(Object object, Object value),只不过操作的数据类型为long |
getLong(Object object) | long | 同get(Object object),只不过得到的数据类型为long |
setFloat(Object object, boolean value) | void | 同set(Object object, Object value),只不过操作的数据类型为float |
getFloat(Object object) | float | 同get(Object object),只不过得到的数据类型为float |
setDouble(Object object, boolean value) | void | 同set(Object object, Object value),只不过操作的数据类型为double |
getDouble(Object object) | double | 同get(Object object),只不过得到的数据类型为double |
setChar(Object object, boolean value) | void | 同set(Object object, Object value),只不过操作的数据类型为char |
getChar(Object object) | char | 同get(Object object),只不过得到的数据类型为char |
getName() | String | 得到目标属性的名字,不局限于private修饰符,只要是类中声明的属性 |
getGenericType() | Type | 得到目标属性的类型,不局限于private修饰符 |
getType() | Class<?> | 得到目标属性的类型对应的Class对象 |
getModifiers() | int | 得到目标属性的修饰符值(private为2、protected为4、public为1、static为8、final为16) |
getDeclaringClass() | Class<?> | 得到目标属性所在类对应的Class对象 |
下面就以一个示例代码来验证Field表中的函数接口的实现,如下:
1). FieldBeReflected.java(被反射的类)
public class FieldBeReflected
{ private static String name; private static String name1; private boolean mBoolean = true; private final byte mByte = 111; private static final short mShort = 22; protected static int mInt; protected static long mLong; protected static float mFloat; protected static double mDouble; public static char mChar; }
2). ReflectField.java(执行反射调用的类)
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type; import com.stevenhu.field.FieldBeReflected; public class ReflectField
{ public static void main(String[] args) { /*1.Class<?> clazz = Class.forName("com.stevenhu.field.FieldBeReflected"); *2.FieldBeReflected mFieldBeReflected = new FieldBeReflected(); * Class<?> clazz = mFieldBeReflected.getClass(); */ Class<?> clazz = FieldBeReflected.class; try { Field fName = clazz.getDeclaredField("name"); Field fBoolean = clazz.getDeclaredField("mBoolean"); Field fByte = clazz.getDeclaredField("mByte"); Field fShort = clazz.getDeclaredField("mShort"); Field fInt = clazz.getDeclaredField("mInt"); Field fLong = clazz.getDeclaredField("mLong"); Field fFloat = clazz.getDeclaredField("mFloat"); Field fDouble = clazz.getDeclaredField("mDouble"); Field fChar = clazz.getDeclaredField("mChar"); /* * 参数为true,只要是在类中声明的目标属性均可访问, * 为false,则被反射类和反射类在同一个包中时,private目标属性不可访问, * 不在同一个包中时,private、protected目标属性均不可访问 */ fName.setAccessible(true); /*给目标属性设置值(private属性不能访问,但可以通过先调用setAccessible(true)实现访问), * 由于ReflectField类中的name属性是静态的(static),所以方法的第一个实参传入的是 * 目标属性所在类对应的Class对象clazz,也可以是类的实例clazz.newInstance(); */ fName.set(clazz, "reflection"); //得到目标属性的值(private属性不能访问,但可以通过调用setAccessible(true)实现访问) String name = (String) fName.get(clazz); System.out.println(name); fBoolean.setAccessible(true); /*得到目标属性的布尔值,由于ReflectField类中的mBoolean属性是非静态的, * 所以此处的传入实参为目标属性所在类的实例clazz.newInstance() */ boolean mBoolean = fBoolean.getBoolean(clazz.newInstance()); System.out.println(mBoolean); fByte.setAccessible(true); //得到目标属性的Byte类型值 byte mByte = fByte.getByte(clazz.newInstance()); System.out.println(mByte); fShort.setAccessible(true); //得到目标属性的short整型值 short mShort = fShort.getShort(clazz); System.out.println(mShort); fInt.setAccessible(true); //给目标属性设置整型值 fInt.setInt(clazz, 222); //得到目标属性的整型值 int mInt = fInt.getInt(clazz); System.out.println(mInt); fLong.setAccessible(true); //给目标属性设置Long整型值 fLong.setLong(clazz, 2222); //得到目标属性的Long整型值 Long mLong = fLong.getLong(clazz); System.out.println(mLong); fFloat.setAccessible(true); //给目标属性设置float类型值 fFloat.setFloat(clazz, 22222); //得到目标属性的float类型值 float mFloat = fFloat.getFloat(clazz); System.out.println(mFloat); fDouble.setAccessible(true); //给目标属性设置double类型值 fDouble.setDouble(clazz, 222.222); //得到目标属性的double类型值 double mDouble = fDouble.getDouble(clazz); System.out.println(mDouble); //给目标属性设置字符值(private、protected属性不能访问) fChar.setChar(clazz, 'a'); //得到目标属性的字符值(private、protected属性不能访问) char mChar = fChar.getChar(clazz); System.out.println(mChar); //目标属性的名字,不局限于修饰符,只要是类中声明的属性 String name1 = fName.getName(); System.out.println(name1); //目标属性的类型,不局限于修饰符 Type type = fName.getGenericType(); System.out.println(type); //目标属性的类型对应的Class对象 Class<?> clazz1 = fName.getType(); System.out.println(clazz1); //目标属性所在类对应的Class对象 Class<?> clazz2 = fName.getDeclaringClass(); System.out.println(clazz2); //目标属性的权限修饰值(private为2、protected为4、public为1) int modifier = fName.getModifiers(); int modifier1 = fByte.getModifiers(); int modifier2 = fShort.getModifiers(); System.out.println(modifier); System.out.println(modifier1); System.out.println(modifier2); System.out.println(fName.isAccessible()); System.out.println(fChar.isAccessible()); } catch (NoSuchFieldException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
3. Method:
同Fiel一样,一个Method对象对应描述一个类的方法;
Class对象也提供了四种接口函数得到对应方法的Method对象,如下:
1). getMethod(String name, Class<?>... parameterTypes):返回类型为Method,第一个参数name为类中的方法名,第二个参数为可变参数,传入的是参数类型对应的Class对象(方法的参数可能为多个的情况);该函数得到的是描述类中的一个public方法对应的Method对象;
2). getMethods():返回类型为Method类型数组,得到的是描述类中的所有public方法对应的Method对象;
3). Method getDeclaredMethod(String name, Class<?>...parameterTypes):
同getMethod(String name, Class<?>... parameterTypes),只不过得到的Method对象描述的不只是public方法, 还包括
protected、private方法,也是说只要是在类中声明的方法;
4). getDeclaredMethods():getMethods(),得到的是描述类中声明的所有方法(public、protected、private)对应的FMethod对象;
Method类的相关函数接口介绍:
Method类提供的相关接口介绍:(详细参看API)
接口 | 返回类型 | 接口功能实现 |
setAccessible(boolean flag) | void | 参数为true,只要是在类中声明的目标方法均可访问,为false,只有public目标属性可访问 |
invoke(Object receiver, Object... args) | Object | 动态执行调用目标方法,第一个参数为Class对象或者类的实例,第二个参数为可变实参的对象(多个实参) |
getDeclaringClass() | Class<?> | 得到目标方法所在类对应的Class对象 |
getExceptionTypes() | Class<?> | 得到目标方法抛出的异常类型对应的Class对象 |
getGenericExceptionTypes() | Type[] | 得到目标方法抛出的异常类型对应的Type对象 |
getReturnType() | Class<?> | 得到目标方法返回类型对应的Class对象 |
getGenericReturnType() | Type | 得到目标方法返回类型对应的Type对象 |
getParameterTypes() | Class<?>[] | 得到目标方法各参数类型对应的Class对象 |
getGenericParameterTypes() | Type[] | 得到目标方法各参数类型对应的Type对象 |
getModifiers() | int | 得到目标方法修饰符的值 |
getName() | String | 得到目标方法的名字 |
下面就以一个示例代码来验证Method表中的函数接口的实现,如下:
1). MethodBeReflected.java(被反射的类)
package com.stevenhu.method; public class MethodBeReflected { private static String mName; private static int mAge; private static float mWeight; private String getmName() { return mName; } protected void setmName(String mName) { this.mName = mName; } protected static int getmAge() { return mAge; } private static void setmAge(int age) { mAge = age; } private float getmWeight() throws Exception, NoSuchMethodException, SecurityException { return mWeight; } protected void setmWeight(float mWeight) { this.mWeight = mWeight; } private void setAllValues(String name, int age, float weight) { this.mName = name; this.mAge = age; this.mWeight = weight; } }
2)ReflectMethod.java(执行反射的类)
package com.stevenhu.reflection.test; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type; import com.stevenhu.method.MethodBeReflected; public class ReflectMethod
{ /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub Class<?> clazz = MethodBeReflected.class; try { //第一个实参为方法名,第二个实参为方法参数类型对应的class对象 Method nameMethod = clazz.getDeclaredMethod("setmName", String.class); Method ageMethod = clazz.getDeclaredMethod("setmAge", int.class); Method weightMethod = clazz.getDeclaredMethod("setmWeight", float.class); Method allValuesMethod = clazz.getDeclaredMethod("setAllValues", new Class[]{String.class, int.class, float.class}); nameMethod.setAccessible(true); //调用setmName方法,给ReflectMethod类中的属性mName赋值为"stevenhu" nameMethod.invoke(clazz.newInstance(), "lisa"); nameMethod = clazz.getDeclaredMethod("getmName", null); nameMethod.setAccessible(true); //调用getmName方法,得到mName的值 String name1 = (String) nameMethod.invoke(clazz.newInstance(), null); System.out.println(name1); ageMethod.setAccessible(true); /*调用setmAge方法设置年龄,由于该方法是静态方法,所以第一个实参可为类的Class对象clazz, * 也可以是类的对象clazz.newInstance(); */ ageMethod.invoke(clazz, 21); ageMethod = clazz.getDeclaredMethod("getmAge", null); ageMethod.setAccessible(true); //调用getmAge方法,得到之前设置的年龄 int age1 = (Integer) ageMethod.invoke(clazz, null); System.out.println(age1); weightMethod.setAccessible(true); //调用setmWeight方法,设置体重 weightMethod.invoke(clazz.newInstance(), new Float(50.5)); weightMethod = clazz.getDeclaredMethod("getmWeight",null); weightMethod.setAccessible(true); //调用getmWeight方法,得到之前设置的体龄 float weight1 = (Float) weightMethod.invoke(clazz.newInstance(), null); System.out.println(weight1); allValuesMethod.setAccessible(true); /*调用ReflectMethod的setAllValues方法赋值 * 注:此处不能直接传入实参63.5;浮点型必须创建Float对象 * 整型和字符串可创建Integer、String对象,也可以不创建 */ //allValuesMethod.invoke(clazz.newInstance(), new String("stevenhu"), new Integer(23), new Float(63.5)); allValuesMethod.invoke(clazz.newInstance(), "stevenhu", 23, new Float(63.5)); nameMethod = clazz.getDeclaredMethod("getmName", null); nameMethod.setAccessible(true); String name2 = (String) nameMethod.invoke(clazz.newInstance(), null); System.out.println(name2); ageMethod = clazz.getDeclaredMethod("getmAge", null); ageMethod.setAccessible(true); int age2 = (Integer) ageMethod.invoke(clazz.newInstance(), null); System.out.println(age2); weightMethod = clazz.getDeclaredMethod("getmWeight", null); weightMethod.setAccessible(true); float weight2 = (Float) weightMethod.invoke(clazz.newInstance(), null); System.out.println(weight2); //得到目标方法所在类对应的Class对象 Class<?> clazz1 = weightMethod.getDeclaringClass(); //得到目标方法抛出的异常类型对应的Class对象 Class<?>[] clazzs1 = weightMethod.getExceptionTypes(); for (Class cl : clazzs1) { System.out.println(cl); } //得到目标方法抛出的异常类型对应的Type对象 Type[] types1 = weightMethod.getGenericExceptionTypes(); //得到目标方法返回类型对应的Class对象 Class<?> clazz2 = nameMethod.getReturnType(); //得到目标方法返回类型对应的Type对象 Type type = nameMethod.getGenericReturnType(); //得到目标方法各参数类型对应的Class对象 Class<?>[] clazzs2 = allValuesMethod.getParameterTypes(); //得到目标方法各参数类型对应的Type对象 Type[] types2 = allValuesMethod.getGenericParameterTypes(); //得到目标方法修饰符的值 int modifier = ageMethod.getModifiers(); System.out.println(modifier); //得到目标方法的名字 String methodName = nameMethod.getName(); System.out.println(nameMethod.isVarArgs()); } catch (NoSuchMethodException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;public class TestReflect {public String name;private int age;public String getName() {return name;}public void setName(String name) {this.name = name;}public String sayHello() {return "hello";}public String sayHello(String name) {return name + ", hello";}public String sayHello(String name, Date date) {return name + ", hello at " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);}@Overridepublic String toString() {return "the object: name=" + name + ";age=" + age;}/*** @param args*/public static void main(String[] args) {try {// 测试String的生成String testStr = "testString";Class getClassWay1 = testStr.getClass();Class getClassWay2 = String.class;Class getClassWay3 = Class.forName("java.lang.String");System.out.println(getClassWay1 == getClassWay2);System.out.println(getClassWay2 == getClassWay3);String str1 = (String) Class.forName("java.lang.String").newInstance();System.out.println(str1);String str2 = (String) Class.forName("java.lang.String") // 得到字节码即事例对象.getConstructor(StringBuffer.class) // 获得该对象中的特定构造器.newInstance(new StringBuffer("abc")); // 根据构造器产生对象实例System.out.println(str2.charAt(1));System.out.println("==========");/Class<?> clazz = Class.forName("com.huabao.test.Demo");Object obj = clazz.newInstance();System.out.println(obj);Field fname = clazz.getField("name");fname.set(obj, "java");Field fage = clazz.getDeclaredField("age");fage.setAccessible(true);fage.setInt(obj, 100);System.out.println(obj);System.out.println(fage.getInt(obj));System.out.println("==========");Method m0 = clazz.getMethod("getName", null);System.out.println(m0.invoke(obj, null));Method m00 = clazz.getMethod("setName", new Class[] { String.class });System.out.println(m00.invoke(obj, new Object[] { "java111" }));System.out.println(obj);Method m1 = clazz.getMethod("sayHello", new Class[0]);System.out.println(m1.invoke(obj, new Object[0]).toString());Method m2 = clazz.getMethod("sayHello", new Class[] { String.class });System.out.println(m2.invoke(obj, new Object[] { "java world" }).toString());Method m3 = clazz.getMethod("sayHello", new Class[] { String.class, Date.class });System.out.println(m3.invoke(obj, new Object[] { "java world", new Date() }).toString());} catch (Exception e) {e.printStackTrace();}}
}
import java.util.HashMap;public class TestClass {public static void main(String[] args) {Object a = new HashMap();System.out.println(a.getClass().isArray());System.out.println(a.getClass().getGenericSuperclass());System.out.println(a.getClass().getPackage());System.out.println(a.getClass().getSimpleName());System.out.println("+++");for (Class c : a.getClass().getInterfaces()) {System.out.println(c.getName());}System.out.println("+++");System.out.println(a.getClass().getComponentType());System.out.println(a.getClass().getModifiers());System.out.println(a.getClass().isLocalClass());System.out.println(a.getClass().isLocalClass());}}
JDK源码解析
Class
该类主要获得编译后的字节码信息,主要包含类的加载/构造方法/普通方法/属性列表/包信息/父类信息的主要信息
Class类(在java.lang包中,Instances of the class Classrepresent classes and interfaces in a running Javaapplication):
在Java中,每个class都有一个相应的Class对象。也就是说,当我们编写一个类,编译完成后,在生成的.class文件中,就会产生一个Class对象,用于表示这个类的类型信息
获取Class实例的三种方式:
(1)利用对象调用getClass()方法获取该对象的Class实例;
(2)使用Class类的静态方法forName(),用类的名字获取一个Class实例(staticClass forName(String className) Returns the Classobject associated with the class or interface with the given stringname. );
(3)运用.class的方式来获取Class实例,对于基本数据类型的封装类,还可以采用.TYPE来获取相对应的基本数据类型的Class实例
在newInstance()调用类中缺省的构造方法 ObjectnewInstance()(可在不知该类的名字的时候,常见这个类的实例) Creates a new instance of the class represented by this Classobject.
在运行期间,如果我们要产生某个类的对象,Java虚拟机(JVM)会检查该类型的Class对象是否已被加载。如果没有被加载,JVM会根据类的名称找到.class文件并加载它。一旦某个类型的Class对象已被加载到内存,就可以用它来产生该类型的所有对象
public class ClassTest {public static void main(String [] args)throws Exception{String str1="abc";Class cls1=str1.getClass();Class cls2=String.class;Class cls3=Class.forName("java.lang.String");System.out.println(cls1==cls2);System.out.println(cls1==cls3);}}
返回结果为:true,true.
解释:虚拟机只会产生一份字节码, 用这份字节码可以产生多个实例对象。
Method Field
Method
提供关于类或接口上单独某个方法(以及如何访问该方法)的信息。所反映的方法可能是类方法或实例方法(包括抽象方法)。
Method
允许在匹配要调用的实参与底层方法的形参时进行扩展转换;但如果要进行收缩转换,则会抛出 IllegalArgumentException
。
Field
提供有关类或接口的单个字段的信息,以及对它的动态访问权限。反射的字段可能是一个类(静态)字段或实例字段。
Array
允许在执行 get 或 set 访问操作期间进行扩展转换,但如果将发生收缩转换,则抛出一个 IllegalArgumentException
。
Modifier
Modifier 类提供了 static
方法和常量,对类和成员访问修饰符进行解码。修饰符集被表示为整数,用不同的位位置 (bit position) 表示不同的修饰符.
modifer 源码
package java.lang.reflect;import java.security.AccessController;
import sun.reflect.LangReflectAccess;
import sun.reflect.ReflectionFactory;/*** The Modifier class provides {@code static} methods and* constants to decode class and member access modifiers. The sets of* modifiers are represented as integers with distinct bit positions* representing different modifiers. The values for the constants* representing the modifiers are taken from the tables in sections 4.1, 4.4, 4.5, and 4.7 of* <cite>The Java™ Virtual Machine Specification</cite>.** @see Class#getModifiers()* @see Member#getModifiers()** @author Nakul Saraiya* @author Kenneth Russell*/
public
class Modifier {/** Bootstrapping protocol between java.lang and java.lang.reflect* packages*/static {sun.reflect.ReflectionFactory factory =AccessController.doPrivileged(new ReflectionFactory.GetReflectionFactoryAction());factory.setLangReflectAccess(new java.lang.reflect.ReflectAccess());}/*** Return {@code true} if the integer argument includes the* {@code public} modifier, {@code false} otherwise.** @param mod a set of modifiers* @return {@code true} if {@code mod} includes the* {@code public} modifier; {@code false} otherwise.*/public static boolean isPublic(int mod) {return (mod & PUBLIC) != 0;}/*** Return {@code true} if the integer argument includes the* {@code private} modifier, {@code false} otherwise.** @param mod a set of modifiers* @return {@code true} if {@code mod} includes the* {@code private} modifier; {@code false} otherwise.*/public static boolean isPrivate(int mod) {return (mod & PRIVATE) != 0;}/*** Return {@code true} if the integer argument includes the* {@code protected} modifier, {@code false} otherwise.** @param mod a set of modifiers* @return {@code true} if {@code mod} includes the* {@code protected} modifier; {@code false} otherwise.*/public static boolean isProtected(int mod) {return (mod & PROTECTED) != 0;}/*** Return {@code true} if the integer argument includes the* {@code static} modifier, {@code false} otherwise.** @param mod a set of modifiers* @return {@code true} if {@code mod} includes the* {@code static} modifier; {@code false} otherwise.*/public static boolean isStatic(int mod) {return (mod & STATIC) != 0;}/*** Return {@code true} if the integer argument includes the* {@code final} modifier, {@code false} otherwise.** @param mod a set of modifiers* @return {@code true} if {@code mod} includes the* {@code final} modifier; {@code false} otherwise.*/public static boolean isFinal(int mod) {return (mod & FINAL) != 0;}/*** Return {@code true} if the integer argument includes the* {@code synchronized} modifier, {@code false} otherwise.** @param mod a set of modifiers* @return {@code true} if {@code mod} includes the* {@code synchronized} modifier; {@code false} otherwise.*/public static boolean isSynchronized(int mod) {return (mod & SYNCHRONIZED) != 0;}/*** Return {@code true} if the integer argument includes the* {@code volatile} modifier, {@code false} otherwise.** @param mod a set of modifiers* @return {@code true} if {@code mod} includes the* {@code volatile} modifier; {@code false} otherwise.*/public static boolean isVolatile(int mod) {return (mod & VOLATILE) != 0;}/*** Return {@code true} if the integer argument includes the* {@code transient} modifier, {@code false} otherwise.** @param mod a set of modifiers* @return {@code true} if {@code mod} includes the* {@code transient} modifier; {@code false} otherwise.*/public static boolean isTransient(int mod) {return (mod & TRANSIENT) != 0;}/*** Return {@code true} if the integer argument includes the* {@code native} modifier, {@code false} otherwise.** @param mod a set of modifiers* @return {@code true} if {@code mod} includes the* {@code native} modifier; {@code false} otherwise.*/public static boolean isNative(int mod) {return (mod & NATIVE) != 0;}/*** Return {@code true} if the integer argument includes the* {@code interface} modifier, {@code false} otherwise.** @param mod a set of modifiers* @return {@code true} if {@code mod} includes the* {@code interface} modifier; {@code false} otherwise.*/public static boolean isInterface(int mod) {return (mod & INTERFACE) != 0;}/*** Return {@code true} if the integer argument includes the* {@code abstract} modifier, {@code false} otherwise.** @param mod a set of modifiers* @return {@code true} if {@code mod} includes the* {@code abstract} modifier; {@code false} otherwise.*/public static boolean isAbstract(int mod) {return (mod & ABSTRACT) != 0;}/*** Return {@code true} if the integer argument includes the* {@code strictfp} modifier, {@code false} otherwise.** @param mod a set of modifiers* @return {@code true} if {@code mod} includes the* {@code strictfp} modifier; {@code false} otherwise.*/public static boolean isStrict(int mod) {return (mod & STRICT) != 0;}/*** 返回描述指定修饰符中的访问修饰符标志的字符串。* * 返回的修饰符名称的顺序与 The Java Language Specification, Second Edition * 的§8.1.1、§8.3.1、§8.4.3、§8.8.3 和 §9.1.1 中给出的建议修饰符排序是一致的。此方法使用的完整修饰符排序是:* public protected private abstract static final transient volatile synchronized native strictfp interface * 这个类中讨论的 interface 修饰符不是真正的 Java 语言修饰符,它将出现在此方法列出的其他所有修饰符的后面。* 此方法可能返回一个不是有效 Java 实体修饰符的修饰符;换句话说,它没有对该输入表示的可能有效的组合修饰符进行检查。* * */public static String toString(int mod) {StringBuffer sb = new StringBuffer();int len;if ((mod & PUBLIC) != 0) sb.append("public ");if ((mod & PROTECTED) != 0) sb.append("protected ");if ((mod & PRIVATE) != 0) sb.append("private ");/* Canonical order */if ((mod & ABSTRACT) != 0) sb.append("abstract ");if ((mod & STATIC) != 0) sb.append("static ");if ((mod & FINAL) != 0) sb.append("final ");if ((mod & TRANSIENT) != 0) sb.append("transient ");if ((mod & VOLATILE) != 0) sb.append("volatile ");if ((mod & SYNCHRONIZED) != 0) sb.append("synchronized ");if ((mod & NATIVE) != 0) sb.append("native ");if ((mod & STRICT) != 0) sb.append("strictfp ");if ((mod & INTERFACE) != 0) sb.append("interface ");if ((len = sb.length()) > 0) /* trim trailing space */return sb.toString().substring(0, len-1);return "";}/** Access modifier flag constants from tables 4.1, 4.4, 4.5, and 4.7 of* <cite>The Java™ Virtual Machine Specification</cite>*//*** The {@code int} value representing the {@code public}* modifier.*/public static final int PUBLIC = 0x00000001;/*** The {@code int} value representing the {@code private}* modifier.*/public static final int PRIVATE = 0x00000002;/*** The {@code int} value representing the {@code protected}* modifier.*/public static final int PROTECTED = 0x00000004;/*** The {@code int} value representing the {@code static}* modifier.*/public static final int STATIC = 0x00000008;/*** The {@code int} value representing the {@code final}* modifier.*/public static final int FINAL = 0x00000010;/*** The {@code int} value representing the {@code synchronized}* modifier.*/public static final int SYNCHRONIZED = 0x00000020;/*** The {@code int} value representing the {@code volatile}* modifier.*/public static final int VOLATILE = 0x00000040;/*** The {@code int} value representing the {@code transient}* modifier.*/public static final int TRANSIENT = 0x00000080;/*** The {@code int} value representing the {@code native}* modifier.*/public static final int NATIVE = 0x00000100;/*** The {@code int} value representing the {@code interface}* modifier.*/public static final int INTERFACE = 0x00000200;/*** The {@code int} value representing the {@code abstract}* modifier.*/public static final int ABSTRACT = 0x00000400;/*** The {@code int} value representing the {@code strictfp}* modifier.*/public static final int STRICT = 0x00000800;// Bits not (yet) exposed in the public API either because they// have different meanings for fields and methods and there is no// way to distinguish between the two in this class, or because// they are not Java programming language keywordsstatic final int BRIDGE = 0x00000040;static final int VARARGS = 0x00000080;static final int SYNTHETIC = 0x00001000;static final int ANNOTATION= 0x00002000;static final int ENUM = 0x00004000;static boolean isSynthetic(int mod) {return (mod & SYNTHETIC) != 0;}/*** See JLSv3 section 8.1.1.*/private static final int CLASS_MODIFIERS =Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE |Modifier.ABSTRACT | Modifier.STATIC | Modifier.FINAL |Modifier.STRICT;/*** See JLSv3 section 9.1.1.*/private static final int INTERFACE_MODIFIERS =Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE |Modifier.ABSTRACT | Modifier.STATIC | Modifier.STRICT;/*** See JLSv3 section 8.8.3.*/private static final int CONSTRUCTOR_MODIFIERS =Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE;/*** See JLSv3 section 8.4.3.*/private static final int METHOD_MODIFIERS =Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE |Modifier.ABSTRACT | Modifier.STATIC | Modifier.FINAL |Modifier.SYNCHRONIZED | Modifier.NATIVE | Modifier.STRICT;/*** See JLSv3 section 8.3.1.*/private static final int FIELD_MODIFIERS =Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE |Modifier.STATIC | Modifier.FINAL | Modifier.TRANSIENT |Modifier.VOLATILE;// JDK1.7 以后出现了一下几个方法,可以查看对应的(class/interface/constructor/method/field)的可用Modifier/*** Return an {@code int} value OR-ing together the source language* modifiers that can be applied to a class.* @return an {@code int} value OR-ing together the source language* modifiers that can be applied to a class.** @jls 8.1.1 Class Modifiers* @since 1.7*/public static int classModifiers() {return CLASS_MODIFIERS;}/*** Return an {@code int} value OR-ing together the source language* modifiers that can be applied to an interface.* @return an {@code int} value OR-ing together the source language* modifiers that can be applied to an inteface.** @jls 9.1.1 Interface Modifiers* @since 1.7*/public static int interfaceModifiers() {return INTERFACE_MODIFIERS;}/*** Return an {@code int} value OR-ing together the source language* modifiers that can be applied to a constructor.* @return an {@code int} value OR-ing together the source language* modifiers that can be applied to a constructor.** @jls 8.8.3 Constructor Modifiers* @since 1.7*/public static int constructorModifiers() {return CONSTRUCTOR_MODIFIERS;}/*** Return an {@code int} value OR-ing together the source language* modifiers that can be applied to a method.* @return an {@code int} value OR-ing together the source language* modifiers that can be applied to a method.** @jls 8.4.3 Method Modifiers* @since 1.7*/public static int methodModifiers() {return METHOD_MODIFIERS;}/*** Return an {@code int} value OR-ing together the source language* modifiers that can be applied to a field.* @return an {@code int} value OR-ing together the source language* modifiers that can be applied to a field.** @jls 8.3.1 Field Modifiers* @since 1.7*/public static int fieldModifiers() {return FIELD_MODIFIERS;}
}
Type Member
-
public interface Type
Type 是 Java 编程语言中所有类型的公共高级接口。它们包括原始类型、参数化类型、数组类型、类型变量和基本类型。
-
public interface Member
成员是一种接口,反映有关单个成员(字段或方法)或构造方法的标识信息。
AccessibleObject Constructor<T>
-
public class AccessibleObject extends Object implements AnnotatedElement
AccessibleObject 类是 Field、Method 和 Constructor 对象的基类。它提供了将反射的对象标记为在使用时取消默认 Java 语言访问控制检查的能力。对于公共成员、默认(打包)访问成员、受保护成员和私有成员,在分别使用 Field、Method 或 Constructor 对象来设置或获取字段、调用方法,或者创建和初始化类的新实例的时候,会执行访问检查。
在反射对象中设置 accessible 标志允许具有足够特权的复杂应用程序(比如 Java Object Serialization 或其他持久性机制)以某种通常禁止使用的方式来操作对象。
-
public final class Constructor<T> extends AccessibleObject implements GenericDeclaration, Mem
Constructor
提供关于类的单个构造方法的信息以及对它的访问权限。
Constructor
允许在将实参与带有底层构造方法的形参的 newInstance() 匹配时进行扩展转换,但是如果发生收缩转换,则抛出IllegalArgumentException
。
另外与Reflact有关的操作有
InvocationHandler Proxy:
这两个主要与动态代理有关(稍后和设计模式一起总结)
package:
Package
对象包含有关 Java 包的实现和规范的版本信息。通过用于加载类的
实例,可以获取并获得此版本信息。通常,此信息存储在与类一起分发的清单中。ClassLoader
ClassLoader :
类加载器是负责加载类的对象。ClassLoader 类是一个抽象类。如果给定类的二进制名称,那么类加载器会试图查找或生成构成类定义的数据。一般策略是将名称转换为某个文件名,然后从文件系统读取该名称的“类文件”。
每个 Class
对象都包含一个对定义它的 ClassLoader 的引用
。
Reflect Java反射机制相关推荐
- 利用java反射机制 读取配置文件 实现动态类载入以及动态类型转换
作者:54dabang 在spring的学习过程之中,我们能够看出通过配置文件来动态管理bean对象的优点(松耦合 能够让零散部分组成一个总体,而这些总体并不在意之间彼此的细节,从而达到了真正的物理上 ...
- Java反射机制分析指南
一.JAVA是动态语言吗? 一般而言,说到动态言,都是指在程序运行时允许改变程序结构或者变量类型,从这个观点看,JAVA和C++一样,都不是动态语言. 但JAVA它却有着一个非常突出的动态相关机制:反 ...
- 【java】java反射机制,动态获取对象的属性和对应的参数值,并属性按照字典序排序,Field.setAccessible()方法的说明【可用于微信支付 签名生成】...
方法1:通过get()方法获取属性值 package com.sxd.test.controller;public class FirstCa{private Integer num;private ...
- java基础-java反射机制
2019独角兽企业重金招聘Python工程师标准>>> 引述要学习Spring框架的技术内幕,必须事先掌握一些基本的Java知识,正所谓"登高必自卑,涉远必自迩" ...
- java初反射_初始 java 反射机制 (一)
反射机制详解 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为j ...
- Java反射机制--笔记
1.认识Class类 任何一个类都是Class类的实例对象,这个实例对象有三种表示方式. 1 /*java 反射机制*/ 2 // 获取类的方法 3 UserDao userDao = new Use ...
- Java反射机制及API使用
原文地址 反射简单来说,就是动态加载对象,并对对象进行剖析.在Java中的反射机制是指在运行状态中,对于任意一个类,都能够知道并获取这个类的所有属性和方法. Java反射机制的作用: 在运行时判断任意 ...
- 工作中用到的java反射机制_(转)JAVA-反射机制的使用
Java反射机制的实现原理 反射机制:所谓的反射机制就是java语言在运行时拥有一项自观的能力.通过这种能力可以彻底的了解自身的情况为下一步的动作做准备.下面具体介绍一下java的反射机制.这里你将颠 ...
- Java 反射机制分析指南
一.JAVA是动态语言吗? 一般而言,说到动态言,都是指在程序运行时允许改变程序结构或者变量类型,从这个观点看,JAVA和C++一样,都不是动态语言. 但JAVA它却有着一个非常突出的动态相关机制:反 ...
最新文章
- Linux视频切片m3u8,使用ffmpeg+nginx使用视频切片播放
- 多线程下HashMap的死循环
- Swift3字符串转换为其他数据类型
- MyBatis快速入门及深入
- python异常处理关键字_Python中的异常处理
- mysql linux-syn25000是什么_当MySQL数据库遇到Syn Flooding
- 使用iPhone相机和OpenCV来完成3D重建(第一部分)
- java cr_WildFly 10 CR 2发布– Java EE 7,Java 8,Hibernate 5,JavaScript支持热重载
- AUTOSAR专业知识篇(五)-“敏捷”适用于汽车软件开发吗?当我们谈“敏捷”,到底在谈什么?
- java IO流小结
- Mysql(三) Mysq慢查询日志
- Java包hashCode()方法及示例
- 计算机科学与软件工程的关系
- C#自学29—简体字繁体字转换
- cad图纸解析java_Java中的AutoCAD库可读取.dwg文件?
- C# Bitmap GetPixel 效率太低,太慢的替代方法
- 三星电子在中国正式召开三星Galaxy Note20系列新品体验发布会~~~~
- Android 手电筒的开启方法
- Simulink 学习(一)
- windows server 2012 RD服务器