反射中的Constructor和数组反射

  1. 云栖社区>
  2. 博客>
  3. 正文

反射中的Constructor和数组反射

乔布斯之魂 2013-11-07 22:13:00 浏览699
展开阅读全文

一、反射中的Constructor

Constructor类代表某个类中的一个构造方法

        Constructor 翻译过来的意思是"构造函数",它是用来描述一个类中的构造函数的。JDK帮助文档的解释--->Constructor 提供关于类的单个构造方法的信息以及对它的访问权限。

现在我有一个MyConstructor类,用反射分别打印出1,2,3.  

public class MyConstructor {// --------------------------------------1
    public MyConstructor(){
        System.out.println("1");
    }
    public MyConstructor(int i){//--------------------------------------2
        System.out.println("2");
    }
    public MyConstructor(int i,String s){//---------------------------3
        System.out.println("3");
    }
}

下面我们现在打印出一个1

public static void main(String[] args) throws Exception{

      //截的图是JDK帮助文档里面的解释
       
        Constructor myConstructor1 = MyConstructor.class.getConstructor();//这里得到的是标记为1的构造函数(相关知识点方法的重载)

       
        myConstructor1.newInstance();
        //上面的2句话输出结果为1.

        Constructor myConstructor1 = MyConstructor.class.getConstructor(int.class);//这里得到的是标记为2的构造函数(相关知识点方法的重载)
        //开始由于受到反射invoke()的思想,并且没有看帮助文档对newInstance()的解释,然后我直接写了下面的语句
        myConstructor1.newInstance(new MyConstructor());//new MyConstructor()我的意思是传带有myConstructor1的构造函数方法的对象给它调用(这里不懂的同学可以看帮 //助文档Method类中invoke()方法的解释),好嘛这里是我弄混淆了

        写成这样也是错的myConstructor1.newInstance(int.class);

        //输出结果为
       

        //argument type mismatch翻译过来的意思是:参数类型不匹配

        // 最后写成这样就对了

        myConstructor1.newInstance(0);

        //执行输出的结果为2.

        //打印1和打印2都写出来了,想必大家打印出3就不难了。

        Constructor myConstructor1 = MyConstructor.class.getConstructor(int.class,String.class);//这里得到的是标记为3的构造函数(相关知识点方法的重载)
        myConstructor1.newInstance(0,"a");

        //执行输出的结果为3

    }


二、数组反射

     在jdk帮助文档中的Class介绍有这样的话:

什么意思呢?意思就是说如果有2个数组对象,它们具有相同的元素类型和维数的话,那它们的class(在内存中的字节码)也是相同的。

示例代码一:

public static void main(String[] args){
        int [] a1 = new int[3];
        int [] a2 = new int[4];
        int [][] a3 = new int[2][3];
        String[] a4 = new String[3];
        System.out.println(a1==a2);//类型相等,维度相等
        //System.out.println(a1==a4);//类型不等,维度相等--------这句编译报错
        //System.out.println(a1==a3);//类型相等,维度不等--------这句编译报错
    }

输出为:false

咦~~~怎么会是false呢,明明类型相等,维度相等,那为什么还是false呢?后面突然发现a1 == a2比的是对象,它们的内容不相等,所以为false。最后改成下面的正确代码:

public static void main(String[] args){
        int [] a1 = new int[3];
        int [] a2 = new int[4];
        int [][] a3 = new int[2][3];
        String[] a4 = new String[3];
        
        System.out.println(a1.getClass()==a2.getClass());//类型相等,维度相等
        System.out.println(a1.getClass()==a4.getClass());//类型不等,维度相等
        System.out.println(a1.getClass()==a3.getClass());//类型相等,维度不等
    }

这里大家在看下面的结果前可以自己先想想

输出结果为:

true
false
false

在这里有个小插曲下面2张图大家对比下

图一:

图二:

细心的你一定发现了哈,二张图的内容都是一样的,毫无区别,那为什么图二中的内容有编译不通过的呢?

现在我只能告诉你图一的JDK是1.4的,而图二的JDK是1.6的,关于JDk1.5有兴趣的朋友可以改来试试哈,至于为什么会这样,具体原因我也说不出来,因为我不知道,嘿嘿~~~~(拿别人的回答来给大家参考参考吧------->“这是编译报错,你用的比以前的东西高级了,后面两个明显因为是类型都不对,答案是false的就直接编译就报错了再说明白点,编译器版本高了聪明了,觉得这种问题低级所以不想让你编译通过了”对这解释感觉神忽忽的--!)



好奇的人会尝试的运行这个代码:System.out.println(a1.getClass().getName());输入结果为:[I,什么意思呢?[:代表是数组,I:代表是int类型。与之相关的介绍在JDK帮助文档里面有解说。


System.out.println(a3.getClass().getName());//int [][] a3 = new int[2][3];
System.out.println(void.class.getName());

上面两句分别输出:

[[I
void

如果是String[][][][][] test = new String[1][2][3][4][5];会输出什么?



public static void main(String[] args){
        int [] a1 = new int[3];
        int [] a2 = new int[4];
        int [][] a3 = new int[2][3];
        String[] a4 = new String[3];
    
        System.out.println(a1.getClass().getSuperclass().getName());//getSuperclass()得到父类的class
        System.out.println(a4.getClass().getSuperclass().getName());
        //这2句话输出分别为java.lang.Object和java.lang.Object(表明a1和a4的父类都一样)
        //所以
        Object aObj1 = a1;//里氏替换原则
        Object aObj2 = a4;//里氏替换原则

        //下面代码回报编译异常
        Object[] aObj3 = a1;//int [] a1 = new int[3];理解为有一个int[]数组,里面装的是int类型,int类型不属于Object

       
        Object[] aObj4 = a3;//int [][] a3 = new int[2][3];理解为有一个int[]数组,里面装的是int[]类型,int[]类型属于Object

       
        Object[] aObj5 = a4;//String[] a4 = new String[3];理解为有一个String[]数组,里面装的是String类型,String类型属于Object 

       
    }



用反射的方式操作数组

我有一个方法public static void print(Object obj){},这方法是用来打印东西的方法,你传一个对象给我,我就给你打印,这时候问题出现了,你会不会传一个数组给我呢?答案是会的,但是我又怎么知道你传的是数组呢?这时候数组的反射有派上用场了

上代码:

/**
     * 打印对象
     * @param obj 你传来的任何对象,如果是数组,打印里面的每一个元素
     */
    public static void printObject(Object obj){
        Class clazz = obj.getClass();
        //true:代表是数组,false:代表不是数组
        if (clazz.isArray()) {
            int len = Array.getLength(obj);
            for (int i = 0; i < len; i++) {
                System.out.println(Array.get(obj, i));
            }
            System.out.println("另一种获取的方法");
            Object[] tempObj = (Object[]) obj;
            for (Object object : tempObj) {
                System.out.println(object);
            }
        }else{
            System.out.println(obj);
        }
    }

      

public static void main(String[] args){

        printObject(a4);
        printObject("hahaha");

}

输出结果:

a
b
c
另一种获取的方法
a
b
c
hahaha


有一个Object[] a = new Object[]{"a",1};这时候您是说不清这个a是什么类型的,说是int它里面有String,说是String它里面有int,但是可以知道a[0]是什么类型的,a[1]是什么类型的,a[0].getClass().getName();


网友评论

登录后评论
0/500
评论
乔布斯之魂
+ 关注