您的位置:首页 > 编程语言 > Java开发

Java Core 第五章——继承(2)

2011-06-01 21:43 239 查看
1、 泛型数组列表
1) 数组类型的大型在程序执行new以后,大小固定了,不能再扩大数组的大小;
2) ArrayList是一种采用类型参数的泛型类, 在ArrayList后面增加<ClassType>来说明数组列表的元素类型;
3) ArrayList可以在数组列表满以后,自动调整大小;当数组列表满以后,再添加(add方法)元素时,数组列表自动创建一个新的数组,并将所有的对象拷贝的新的数组列表中;
4) 如果能估计到数组列表可能存储的元素数量,可以在填充元素之前调用ensureCapacity(size)分配size个对象的数组,也可以在初始化的时候指定大小 new ArrayList<ClassType>(size); 然后再增加对象到数组列表中,效率会比较高;如果不指定数组列表的大小,Java会默认分配10个;
5) 数组列表的容量和数组的大小是不同的;前者可以扩大,数组列表的size方法可以返回当前实际存储的元素个数;
6) 一旦确定数组列表的大小不再变化时,使用trimToSize方法将存储区域大小调整为当前数量所需的元素数目,垃圾回收器将回收多余的存储空间;
7) 数组列表的访问不能通过数组的下标[]方式访问,修改器set(index, elem), 访问器get(index), index从0开始,到size() -1, 如果index > size()-1, 则出错;
8) Java SE 5.0以前版本没有泛型类,原始的ArrayList可以存储任何Object的元素,get方法返回类型为Object,因此必须进行类型转换;原始的ArrayList存在一定的危险性,原因是它的存储类型为Object,但是所有的类都是Object的子类,这样就可以将不同的类型存储到ArrayList中;
9) 如果需要用数组下标[]访问,则可以把ArrayList对象转化成Array,使用toArray(array);
10) 数组列表可以通过add在尾部添加,也可以指定在中间某个位置插入,如果在中间插入,则后面的元素 需要向后移动一个位置;如果插入新元素后,元素个数超过了容量,数组列表就被重新分配空间;
11) 数组列表可以通过remove删除某个位置的元素,这个元素后面的元素将向前移动,size 将减少1;
12) 数组列表也可以通过for each遍历;
2、 对象包装器和自动打包
1) 在某些泛型类型中,不能使用基本数据类型作为类型参数,Java提供了基本数据类型对应的对象类型,把这些类型称为包装器,包装器类型:Integer,Long, Float,Double,Short,Byte,Character,Void和Boolean(前六个数值包装器派生自超类Number);
2) 对象包装器是不可变的,即一旦构造了包装器的值,就不允许更改包装在其中的值;
3) 对象包装器不允许继承, 因此它们是final类;
4) 一般使用包装器类比使用对应的基本类型效率要低得多;
5) 在Java语句中,将对应的基本类型自动转换成对应的包装器类型,这个过程称自动打包;相反,将包装器类型自动转换成对应的基本类型的过程,称为自动拆包;
6) 打包和拆包是编译器完成的,在必须的时候,打包或者拆包插入一定的代码,java虚拟机执行相应的字节码;
7) ==运算也可以应用于包装器类对象, 只不过检测的是对象是否指向同一个存储区;
8) 自动打包规范要求boolean、byte、char<=127; [-128, 127]之间的short和int被包装到固定的对象中,也就是说如果有两个包装器对象的值为[-128,127]之间,那么这两个包装器对象引用了同一个固定的对象;
3、 参数量可变的方法
1)Java SE5.0中,所有方法的参数个数都是固定的。Java新增加了支持参数可以变的方法。printf方法就是参数量可变的。
public class PrintStream
{
public PrintStream printf(String fmt, Object… args)
{
return format(fmt, args);
}
}
实际上,printf接收了两个参数,一个是fmt 字符串,一个是args的Object数组(保存着所有的参数,如果调用者提供的是整型等基本类型,自动打包功能将它们自动打包成对应的对象类型),方法处理的时候,解析字符串中fmt的格式说明符第i个,从数组中取第i个值;
2) 用户也可以自定义可变参数的方法,方法中可以使用for-each取每个参数
3) 允许将一个数组传递给可变参数方法的最后一个参数;也就是说,可变参数一定是方法中的最后一个参数,而且不支持多个可变参数;
4、 枚举类型
1) 比较两个枚举类型的值时,不要使用equals,直接使用==;
2) 所有的枚举类型都是Enum类的子类,它们继承了这个类的很多方法, 最常用的是toString返回枚举常量名;
3) 每个枚举类型都有一个静态的values方法, 它返回一个包含全部枚举值的数组;

5、 反射
1) 能够分析类能力的程序被称为反射;
2) 在程序运行期间,Java运行时始终所有的对象维护一个被称为运行是的类型标识,这个信息保存着每个对象所属的类地足迹,虚拟机利用运行时信息选择相应的方法执行,Java中的Class类就是保存这些信息的;
3) 对象的getClass()方法(Object类的方法)获取对象类信息;
4) 可以用Class类的静态方法forName(类名)获取类名对应的Class对象,如果不存在这样的类,将会抛异常;
5) 任意类型T(包括基本类型和对象类型), T.class将代表匹配的类对象;一个Class对象实际上代表了一个类型,而这个类型未必是一种类;
6) JVM为每个类型管理一个Class对象,可以利用==运算符实现两个类对象的比较操作;
7) 可以用Class类的newInstance()方法, 创建这个Class对象代表的类的对象实例,这个类必须有默认的构造器;
8) 利用反射分析类的能力,可以获取对象构造器Constructor, 方法 Method,域 Field,参考java.lang.reflect;
9) 利用运行时的反射调试程序;Field的get方法可以获取运行时的值,但是当Field是私有时,Java安全机制不允许方法, 为了达到目的,Java中Field, Method和Constructor类对象有setAccessible(true)对这三类的对象授权;
10) 反射机制用来创建泛型数组,对于Object[]数组作参数,当在进行数组拷贝的时候,由于不知道数组存放的真实类型,可以利用反射机制。
11) 方法指针,虽然Java语言中没有方法指针,但是反射包中却有此用法,Method的invoke方法就是通过对象的方法作为参数,执行对象的方法,具体参考API。
6、 总结
1) 将公共操作和域放在超类中;
2) 不要使用protected修饰域;
3) 使用继承实现”is-a”关系,但是不可滥用,一定要分析清楚超类的域和操作在子类使用使用;
4) 除非所有的继承方法都有意义,否则不要使用继承;
5) 在覆盖方法时,不要改变预期的行为;
6) 使用多态,而不是类型信息;
7) 不要过多使用反射,反射很脆弱,通常会出现一些编译器很难帮助程序员发现的错误;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: