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);
	}

	@Override
	public 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 keywords
    static 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引用

时间: 2024-10-08 12:27:29

Reflect Java反射机制的相关文章

java反射机制reflect 分析Object对象

直接看一个实例吧 </pre><pre name="code" class="java">package reflect; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; class Behavior { privat

java反射机制(一)—— 利用反射机制实例化对象

一.Java有着一个非常突出的动态相关机制:Reflection,用在Java身上指的是我们可以于运行时加载.探知.使用编译期间完全未知的classes.换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体.或对其fields设值.或唤起其methods.(度娘文库是这么说的) 二.这篇文章主要介绍一下通过反射机制去实例化一个类的对象,然后调用其方法.本文主要介绍两种方式,第一种就是通过构造函数来实例化,第二种就是通过Cl

【java】java反射机制,动态获取对象的属性和对应的参数值,并属性按照字典序排序,Field.setAccessible()方法的说明【可用于微信支付 签名生成】

方法1:通过get()方法获取属性值 package com.sxd.test.controller; public class FirstCa{ private Integer num; private String name; private Boolean flag; public Integer getNum() { return num; } public void setNum(Integer num) { this.num = num; } public String getNam

Java 反射机制

使用 Java 反射机制可以在运行时期检查 Java 类的信息,检查 Java 类的信息往往是你在使用 Java 反射机制的时候所做的第一件事情,通过获取类的信息你可以获取以下相关的内容: Class 对象 类名 修饰符 包信息 父类 实现的接口 构造器 方法 变量 注解 除了上述这些内容,还有很多的信息你可以通过反射机制获得,如果你想要知道全部的信息你可以查看相应的文档 JavaDoc for java.lang.Class 里面有详尽的描述. 在本节中我们会简短的涉及上述所提及的信息,上述的

Java反射机制浅析

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制. "程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言".从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言.但是JAVA有着一个非常突出的动态相关机制:Reflection,用在Java身上指的是我们可以于运行时加载.探知.使用

java反射机制分析

本文转自:http://www.cnblogs.com/gulvzhe/archive/2012/01/27/2330001.html 浅显易懂,值得收藏 Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象, 都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制.反射的概念是由Smith在1982年 首次提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力.这一概念的提出很快引发了

java 反射机制:运行时的类信息(为框架服务的Bug存在)

反射机制:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制. 换一种引出反射的说法是:当通过反射与一个未知的类型的对象打交道是,JVM只是简单地检查这个类,看它是属于哪个特定的类(就想RTTI那样).在用它做其他事情之前必须先加载那个类的Class对象.因此,那个类的.class文件对于JVM来说必须是可获取的:那么在本地机器上,要么通过网络获得

java反射机制简介

1.字节码.所谓的字节码就是当java虚拟机加载某个类的对象时,首先需要将硬盘中该类的源代码编译成class文件的二进制代码(字节码),然后将class文件的字节码加载到内存中,之后再创建该类的对象 2.java反射的基础是Class类(注意不是小写的class),Class类实例代表着内存中的一份字节码.常见的获取Class类对象的方法如下(第一种为对象的方法,第二种为类的方法): Dog dog = new Dog(); Class dogClass = dog.getClass(); Cl

【转载】Java反射机制详解

转自:http://baike.xsoftlab.net/view/209.html#3_8 1反射机制是什么 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制. 2反射机制能做什么 反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类: 在运行时构造任意一个类的对象: 在运行时判断任意一个类所具有的成员变量和方法: 在运行时调用任意一个