黑马程序员--反射具体应用

android培训java培训、期待与您交流!

种预定义的 Class 对象,表示八个基本类型void。这些类对象由 Java 虚拟机创建,与其表示的基本类型同名,即 boolean、byte、char、short、int、long、floatdouble

数组类型的Class实例对象

Class.isArray()
总之,只要是在源程序中出现的类型,都有各自的Class实例对象,例如,int[],void…

Constructor类

Constructor 提供关于类的单个构造方法的信息以及对它的访问权限。
得到某个类所有的构造方法:

Constructor[] constructors = Class.forName("java.lang.String").getConstructors();

得到某个构造方法:

Constructor constructor = Class.forName("java.lang.String").getConstructor(StringBuffer.class);

创建实例对象
通常方式:String str = new String(new StringBuffer("abc"));
反射方式:String str = (String)constructor.newInstance(new StringBuffer("abc"));
Class.newInstance()方法:

String obj = (String)Class.forName("java.lang.String").newInstance();

该方法内部先得到默认的构造方法,然后用该构造方法创建实例对象.
该方法内部的具体代码是怎么写的呢?用到了缓存机制来保存默认构造方法的实例对象.

Field类

Field 提供有关类或接口的单个字段的信息,以及对它的动态访问权限。反射的字段可能是一个类(静态)字段或实例字段。
重要方法:

Object get(Object obj) 
          返回指定对象上此 Field 表示的字段的值。 
void set(Object obj, Object value) 
          将指定对象变量上此 Field 对象表示的字段设置为指定的新值。 

练习:
将任意一个对象中的所有String类型的成员变量所对应的字符串内容中的”b” 改成”a”。

private static void changeStringValue(Object obj)throws Exception{
    Field[] fields = obj.getClass().getFields();
    for(Field field:fields){
        if(field.getType() == String.class){
            String oldValue = (String)field.get(obj);
            String newValue = oldValue.replace('b','a');
            field.set(obj,newValue);
        }
    }

Method类

Method 提供关于类或接口上单独某个方法(以及如何访问该方法)的信息。所反映的方法可能是类方法或实例方法(包括抽象方法)。

Method 允许在匹配要调用的实参与底层方法的形参时进行扩展转换;但如果要进行收缩转换,则会抛出 IllegalArgumentException

得到类中的某一个方法:

Method chatAtMethod = Class.forName("java.lang.String").getMethod("chatAt",int.class);

调用方法:
通常方式:str.chatAt(1)
反射方式:chatAtMethod.invoke(str,1);
如果传递给Method对象的invoke()方法的第一个参数为null,说明该Method对象对应的是一个静态方法

JDK1.4和JDK1.5的invoke方法的区别:

  • JDK1.5: public Object invoke(Object obj,Object… args)
  • JDK1.4: public Object invoke(Object obj,Object[] args),按1.4的语法,需要将一个数组作为参数传递给invoke方法时, 数组中的每个元素分别对应被调用方法中的一个参数,所以,调用chatAt方法的代码也可以用JDK1.4改写为chatAtMethod.invoke(“str”,new Object[]{1})形式.
Object invoke(Object obj, Object... args) 
          对带有指定参数的指定对象调用由此 Method 对象表示的底层方法。 

用反射方式执行某个类中的main方法

String startingClassName = args[0];
Method mainMethod = Class.forName(startingClassName).getMethod("main",String[].class);
mainMethod.invoke(null,(Object)new String[]{"111","222","333"});

调用时传递数组参数出现问题的解决方法:

  • mainMethod.invoke(null,new Object[]{new String[]{“xxx”}});
  • mainMethod.invoke(null,(Object)new String[]{“xxx”});编译器会做特殊处理,编译时不把参数当作数组看待,也就不会数组打散成若干个参数了.

Array类

Array 类提供了动态创建和访问 Java 数组的方法。

Array 允许在执行 getset 操作期间进行扩展转换,但如果发生收缩转换,则抛出 IllegalArgumentException

static Object get(Object array, int index) 
          返回指定数组对象中索引组件的值。 
static int getLength(Object array) 
          以 int 形式返回指定数组对象的长度。 
static void set(Object array, int index, Object value) 
          将指定数组对象中索引组件的值设置为指定的新值。 

练习:
打印数组中各个元素,或者打印一个元素

private static void printObject(Object obj){
    Class clazz = obj.getClass();
    if(clazz.isArray()){
        int len = Array.getLength(obj);
        for(int i=0;i<len;i++){
            System.out.println(Array.get(obj,i));
        }
    }else{
        System.out.println(obj);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值