java 反射

反射

能够分析类能力的程序被称为反射。反射机制可以用来:

  • 在运行时分析类;
  • 在运行时查看对象;
  • 实现通用的数组操作代码;
  • 使用Method对象,以类似于函数指针的方式调用函数。
通过反射分析类
public class ReflectionTest {
    public static void main(String[] args) {
        String name;
        if (args.length > 0)
            name = args[0];
        else {
            Scanner in = new Scanner(System.in);
            System.out.println("Enter class name (e.g. java.util.Date): ");
            name = in.next();
        }

        try {
            Class cls = Class.forName(name);
            Class superCls = cls.getSuperclass();
            String modifiers = Modifier.toString(cls.getModifiers());

            if (modifiers.length() > 0)
                System.out.print(modifiers + " ");
            System.out.print("class " + cls.getName());

            if (superCls != null && superCls != Object.class)
                System.out.print(" extends " + superCls.getName());
            System.out.println("\n{");
            showConstructor(cls);
            System.out.println();
            showFields(cls);
            System.out.println();
            showMethods(cls);
            System.out.println("}");
        }
        catch(ClassNotFoundException e){
            e.printStackTrace();
        }
    }

    private static void showConstructor(Class cls){
        Constructor[] constructors=cls.getDeclaredConstructors();

        for(Constructor constructor:constructors){
            String name=constructor.getName();
            System.out.print("\t");
            String modifiers=Modifier.toString(constructor.getModifiers());

            if(modifiers.length()>0)
                System.out.print(modifiers+" ");
            System.out.print(name+"(");

            Class[] paramTypes=constructor.getParameterTypes();

            for(int i=0;i<paramTypes.length;i++){
                if(i<paramTypes.length-1)
                    System.out.print(paramTypes[i].getName()+", ");
                else
                    System.out.print(paramTypes[i].getName());
            }

            System.out.println(");");
        }
    }

    private static void  showFields(Class cls){
        Field[] fields=cls.getDeclaredFields();
        for(Field field:fields){
            Class type=field.getType();
            String name=field.getName();
            String modifiers=Modifier.toString(field.getModifiers());
            System.out.print("\t");
            if(modifiers.length()>0)
                System.out.print(modifiers+" ");
            System.out.println(type.getName()+" "+name+";");
        }
    }

    private static void showMethods(Class cls){
        Method[] methods=cls.getDeclaredMethods();
        for(Method method:methods){
            String name=method.getName();
            String modifiers=Modifier.toString(method.getModifiers());
            System.out.print("\t");
            if(modifiers.length()>0)
                System.out.print(modifiers+" ");
            System.out.print(name+"(");
            Class[] paramTypes=method.getParameterTypes();
            for(int i=0;i<paramTypes.length;i++){
                if(i<paramTypes.length-1){
                    System.out.print(paramTypes[i].getName()+", ");
                }
                else
                    System.out.print(paramTypes[i].getName());
            }
            System.out.println(");");
        }
    }
}

上述程序会打印出输入类(如java.lang.String)的所有constructors,fields,methods(反射方法名中的Declared表明只获取本类中的信息,而不包括父类)。

通过反射查看对象
public class Test {
   public static void main(String[] args) throws Exception {
       ReflectField testObj=new ReflectField("han feng");
       Class cls=testObj.getClass();
       Field mask=cls.getDeclaredField("mask");
       Object v=mask.get(testObj);

       System.out.println(v);//反射机制获取实例的特定域值
       System.out.println(testObj.mask);//传统方法
   }
}
class ReflectField{
    public String mask;
    public ReflectField(String mask){
        this.mask=mask;
    }
}
通过反射操作数组

通过一个数组扩容的例子来说明反射机制在数组上的使用。

public static Object goodCopyOf(Object a,int newLength){//a is an array
	Class cls=a.getClass();
	if(!cls.isArray())return null;
	Class componentType=cls.getComponentType();
	int length=Array.getLength(a);
	Object newArray=Array.newInstance(componentType,newLength);
	Arrays.copy(a,0,newArray,0,Math.min(length,newLength));
	return newArray;
}

函数goodCopyOf()数组参数a的类型设置为Object的原因在于:int[]可以转化为 Object,但是不能转化为Object[],这样该函数的泛型能力更强。

通过反射使用方法
public class Test {
   public static void main(String[] args) throws Exception {
      ReflectMethod testObj=new ReflectMethod();
      Class cls=testObj.getClass();
      Method hello=cls.getDeclaredMethod("hello",String.class);
      Method introduce=cls.getDeclaredMethod("introduce");
      hello.invoke(testObj,"I love you.");//通过反射调用实例方法
      introduce.invoke(null);//通过反射调用类方法
   }
}
class ReflectMethod{
    public void hello(String message){
    	System.out.println("he said:\""+message+"\"");
    }
    public static void introduce(){
    	System.out.println("My name is "+ReflectMethod.class.getName());
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值