黑马程序员_java高级篇反射Day11

  ----------------------ASP.Net+Android+IOS开发.Net培训、期待与您交流! --------

 

                                                黑马程序员_java高级篇反射Day11

 

           今天是我的第50篇博客,从快乐杂谈到黑马博客记录,都记录着自己的成长.

 

#用反射的方法调用main函数#


知识点1: 

args[0]是传进来的值,就是main(String[] args)中的args中的值。

String startNAME=args[0];
Method m=Class.forName(startNAME).getMethod("main",String[].class);
 

//调用invoke方法,使用指定的参数指定的对象上的基本方法。各个参数自动解包,以匹配原始的形式参数。

m.invoke(null, new Object[]{newString[]{"1"}});
 

为什么getMethod("main",String[].class);中后面是String[].class,因为

Main方法原来的参数也是String[](数组),现在只不过是以类的字节码传进去

知识点2

invoke方法的解释,第一个参数表示对象,null表示不需要建立对象就能直接调用的方法,不就是静态方法吗。如果你要调用的不是静态方法,你需要先建立一个对象,第一个参数就是这个对象名。第二个参数是你要传入的值,main方法我们要传入的是一个字符数组, new String[]{"1"},这里确实是一个字符数组没错,但是java为了兼容JDK1.4有一点问题,解决的办法。这里不加 new Object[]有问题,因为JDK1.5为了兼容1.4时,当我们给他一个new String[]{"1"}时,它不把你当成是一个数组,把你当成一个参数,因为它会打开数组newString[],所以我们给他传一个object数组,这样打开的第一个就是我们的对象。

m.invoke(null, new Object[]{newString[]{"1"}});

我们调用的类的main方法

public static void main(String[] args)
    {
       System.out.println(args[0]);
    }
 

#数组的反射#


知识点1,数组反射的第一个问题,我们要注意数组的维数与类型。

如下:

//维数
       int[] a=new int[3];
       int[] b=new int[4];
       int[][] c=new int[3][4];
      
       System.out.println(a.getClass()==b.getClass());
       System.out.println(b.getClass()==c.getClass());


第一个会输出true,因为他们调用的是同一个字节码。第二个输出false,他们的维数不一样。

 

知识点2,数组赋值问题

   这里的知识点是,int[]表示数组里面放int,由于a数组int并不是object。,所以赋值时会出错。但是c可以,因为c里面是二维数组。表示数组里面放数组,这样数组是object的

Object obj=a;
Object[] obj1=c;
System.out.println(a);
System.out.println(Arrays.asList(a));
System.out.println(Arrays.asList(d));
System.out.println(a.getClass());


为什么第一个输出是[[I@182f0db],而第二个输出就是[a, b, c],我们查看他的方法,发现List(Object[]),在jdk1.4中,由于List(Object[]),里面是object数组,当我们传入int[]时,因为int并不是object,所以我们就按照jdk1.5的来,List(Object...),传入可变参数对象,当我们传入的是可变参数对象,那么int[]就相当于一个对象。

 

知识点3,获得数组类的值

我们可以通过以下函数来获得数组里面的值,我们只要传给他一个对象。

//通过这个函数,我们可以获得数组内的值

public static void printObject(Object obj)
    {
        Class   c= obj.getClass();
        if(c.isArray())
    {
       int len=Array.getLength(obj);
       for(int i=0;i<len;i++)
       {
           System.out.print(Array.get(obj,i));
       }
    }
        else
        {
          System.out.println(obj);  
       }
      
    }
 


如:

String[] d=new String[]{"a","b","c"};
printObject(d);


 

我们是否可以获得数组的类型呢?对于获得像

int[] a=new int[2];

要获得a前面的int类型是不太可能的。只能获得某个元素的类型

 

#看一看HashSet与ArrayList的区别#‘


HashSet中如果加入同一个对象会出现覆盖,但ArrayList不会。

这是为什么呢?因为对于数组它是一个一个顺序的放进去的,但是你的

HashSet不一样,它会检查是否含有相同的元素,如果相同,则不能放进去,这里检查的只是内存地址,并不是我们所说的值。

如下:

Collection coll=new HashSet();
Reflectpoint rp=new Reflectpoint(3,3);
Reflectpoint rp1=new Reflectpoint(3,4);
Reflectpoint rp2=new Reflectpoint(3,5);
Reflectpoint rp3=new Reflectpoint(3,3);

coll.add(rp);
coll.add(rp1);
coll.add(rp2);
coll.add(rp3);
System.out.println(coll.size());


输出的是4个,因为他们是四个不同的对象,虽然rp与rp3的值相同。如果我们在这再添加一个coll.add(rp);现在输出还是4,因为rp现在并没有被添加进去。

 

##重点:一个是hashcode到底有什么作用?另一个是内存泄露问题##

 

Hashcode是Reflectpoint这个类中的代码
 
public class Reflectpoint {
    int x;
    int y;
    public Reflectpoint(int x, int y){
       super();
       this.x = x;
       this.y = y;
}
}


hash每一个对象,算出来时,我们会把它放到hash表中,如当我们没有,在Reflectpoint类中加Hashcode(选中int x,int y,右键,hashcode生成代码),当我加入值相同的对象,hash表把他们放到不同的区域,所以检测不出来,所以就放进去了,但是当我们加入hashcode时,由于可以算出,值一样时,就加不进去了。

 

这又衍生了一个问题,就是内存泄露问题,看下面的语句。

 

内存泄露:功能已完成的对象,不释放占用的资源。

 

rp.x=7;
coll.remove(rp);


如果我们将rp.x=7;改了,我们再一次删除时,hash找不到这个对象,因为他通过hashcode算出这个对象的hash值在hash表中找不到。所以删不了。这就导致内存泄露。

 ----------------------ASP.Net+Android+IOS开发.Net培训、期待与您交流! --------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值