----------------------ASP.Net+Android+IOS开发.Net培训、期待与您交流! --------
今天是我的第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培训、期待与您交流! --------