一、JDK5新特性:
1、可变参数:
public class VarableParameter {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(add(2,3));
System.out.println(add(2,3,5));
}
public static int add(int x,int... args){
int sum = x;
/* for(int i=0;i<args.length;i++){
sum += args[i];
}*/
for(int arg : args){
sum += arg;
}
return sum;
}
}
2、自动折装箱
public class AutoBox {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Integer iObj = 3;
System.out.println(iObj + 12);
String s1 = new String("abc");
String s2 = new String("abc");
Integer i1=10;
Integer i2=10;
System.out.println(i1 == i2);//true:-128~127
Integer i3 = 137;
Integer i4 = 137;
System.out.println(i3 == i4);//false
Integer i5 = Integer.valueOf(213);
Integer i6 = Integer.valueOf(213);
System.out.println(i5==i6);//false
}
}
二、享元模式(flyweight):
描述:如果很多很小的对象,他们有很多相同的属性,那就可以把这些相同的属性变成一个内部对象,还有一些不同的对象可以把它变为外部的属性,通过方法的参数部传入。
就像windows中的图标,对于.txt文件或文件夹,那么他们的图标都是相同的,只是他的文件名或文件夹名及文件里的内容或文件夹里的内容不相同。
三、反射
反射就是把Java类中的各种成份(变量,构造函数,方法)映射成相对应的Java类。
1、对类的public构造方法的反射用Constructor类及其方法,例如对String的这个方法进行反射
public String(String original) {
int size = original.count;
char[] originalValue = original.value;
char[] v;
if (originalValue.length > size) {
// The array representing the String is bigger than the new
// String itself. Perhaps this constructor is being called
// in order to trim the baggage, so make a copy of the array.
int off = original.offset;
v = Arrays.copyOfRange(originalValue, off, off+size);
} else {
// The array representing the String is the same
// size as the String, so no point in making a copy.
v = originalValue;
}
this.offset = 0;
this.count = size;
this.value = v;
}
可以用如下的方式:
getConstructor():Returns a Constructor
object that reflects the specified public constructor of the class represented by thisClass
object.
Constructor constructor1 = String.class.getConstructor(StringBuffer.class);
String str2 = (String)constructor1.newInstance(/*"abc"*/new StringBuffer("abc"));
2、对类或接口的成员变量进行反射用Field类有其方法,例如对类ReflectPoint进行反射,得到他所对应的变量及变量的值
public class ReflectPoint {
private int x;
public int y;
}
getField(): Returns a Field
object that reflects the specifiedpublic member field of the class or interface represented by thisClass
object.
getDeclaredField():Returns a Field
object that reflects the specifieddeclared field of the class or interface represented by this Class object.
ReflectPoint pt1 = new ReflectPoint(3,5);
Field fieldY = pt1.getClass().getField("y");
//fieldY的值是多少?是5,错!fieldY不是对象身上的变量,而是类上,要用它去取某个对象上对应的值
System.out.println(fieldY.get(pt1));
Field fieldX = pt1.getClass().getDeclaredField("x");
fieldX.setAccessible(true);
System.out.println(fieldX.get(pt1));
如果变量定义为private,那么可以用Field.setAccessible(true)方法让其可以访问,这叫做暴力反射。
3、对类或接口的方法进行反射用Method类及其方法,例如对String类的charAt()方法进行反射:
public char charAt(int index) {
if ((index < 0) || (index >= count)) {
throw new StringIndexOutOfBoundsException(index);
}
return value[index + offset];
}
getMethod(): Returns a Method
object that reflects the specifiedpublic member method of the class or interface represented by thisClass
object.
getDeclaredMethod ():Returns a Method
object that reflects the specifieddeclared method of the class or interface represented by thisClass
object.
Method methodCharAt = String.class.getMethod("charAt", int.class);
System.out.println(methodCharAt.invoke(str1, 1));
System.out.println(methodCharAt.invoke(str1, new Object[]{2}));
对于静态的方法,可以把Object参数设为null如下对main()的反射:
Method mainMethod = Class.forName(startingClassName).getMethod("main", String[].class);
//mainMethod.invoke(null, new Object[]{new String[]{"111","222","333"}});
mainMethod.invoke(null, (Object)new String[]{"111","222","333"});
如果是数组做为参数,那么他接收的参数是Object,那就要把数组做包装或强制转换为Object,因为我们知道Object是"cosmos superclass"。
4、对数组的反射:
int [] a1 = new int[]{1,2,3};
int [] a2 = new int[4];
int[][] a3 = new int[2][3];
String [] a4 = new String[]{"a","b","c"};
System.out.println(a1.getClass() == a2.getClass());
System.out.println(a1.getClass().getName());
System.out.println(a1.getClass().getSuperclass().getName());
System.out.println(a4.getClass().getSuperclass().getName());
四、HashSet与HashCode
1、通常来说,一个类的两个实例对象用equals()方法比较的结果相等时,它们的哈希码也必须相等,但反之则不成立,即equals方法比较不相等的对象可以有相同的哈希码,或者说哈希码相等的两个对象的equals方法比较的结果可以不相等,例如,字符串“BB”和“Aa”的equals比较方法肯定不相等,但它们的hashCode方法返回值却相等
2、当一个对象被存储进HashSet集合以后,就不能修改这个对象中的那些参与计算哈希值的字段了,否则,对象修改后的哈希值与最初存储进HashSet集合中时的哈希值就不相同了,在这种情况下,即使在contains方法使用该对象的当前引用作为参数去HashSet集合中检索对象,也将返回找不到对象的结果,这也导致无法从HashSet集合对象中单独删除当前对象,从而造成内存泄漏。
Collection collections = new HashSet();
ReflectPoint pt1 = new ReflectPoint(3,3);
ReflectPoint pt2 = new ReflectPoint(5,5);
ReflectPoint pt3 = new ReflectPoint(3,3);
collections.add(pt1);
collections.add(pt2);
collections.add(pt3);
collections.add(pt1);
//pt1.y = 7;
collections.remove(pt1);
System.out.println(collections.size());
如果把//pt1.y=7的注释去掉,则输出为2。