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

1、  泛型数组列表

1)  数组类型的大型在程序执行new以后,大小固定了,不能再扩大数组的大小;

2)  ArrayList是一种采用类型参数的泛型类, ArrayList后面增加<ClassType>来说明数组列表的元素类型;

3)  ArrayList可以在数组列表满以后,自动调整大小;当数组列表满以后,再添加(add方法)元素时,数组列表自动创建一个新的数组,并将所有的对象拷贝的新的数组列表中;

4)  如果能估计到数组列表可能存储的元素数量,可以在填充元素之前调用ensureCapacitysize)分配size个对象的数组,也可以在初始化的时候指定大小 new ArrayList<ClassType>(size); 然后再增加对象到数组列表中,效率会比较高;如果不指定数组列表的大小,Java会默认分配10个;

5)  数组列表的容量和数组的大小是不同的;前者可以扩大,数组列表的size方法可以返回当前实际存储的元素个数;

6)  一旦确定数组列表的大小不再变化时,使用trimToSize方法将存储区域大小调整为当前数量所需的元素数目,垃圾回收器将回收多余的存储空间;

7)  数组列表的访问不能通过数组的下标[]方式访问,修改器set(index, elem), 访问器get(index), index0开始,到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提供了基本数据类型对应的对象类型,把这些类型称为包装器,包装器类型:IntegerLong FloatDoubleShortByteCharacterVoidBoolean(前六个数值包装器派生自超类Number);

2)  对象包装器是不可变的,即一旦构造了包装器的值,就不允许更改包装在其中的值;

3)  对象包装器不允许继承, 因此它们是final类;

4)  一般使用包装器类比使用对应的基本类型效率要低得多;

5)  Java语句中,将对应的基本类型自动转换成对应的包装器类型,这个过程称自动打包;相反,将包装器类型自动转换成对应的基本类型的过程,称为自动拆包;

6)  打包和拆包是编译器完成的,在必须的时候,打包或者拆包插入一定的代码,java虚拟机执行相应的字节码;

7)  ==运算也可以应用于包装器类对象, 只不过检测的是对象是否指向同一个存储区;

8)  自动打包规范要求booleanbytechar<=127;  [-128 127]之间的shortint被包装到固定的对象中,也就是说如果有两个包装器对象的值为[-128127]之间,那么这两个包装器对象引用了同一个固定的对象;

3、  参数量可变的方法

1Java SE5.0中,所有方法的参数个数都是固定的。Java新增加了支持参数可以变的方法。printf方法就是参数量可变的。

public class PrintStream

{

public PrintStream printf(String fmt, Object… args)

{

return format(fmt, args);

}

}

实际上,printf接收了两个参数,一个是fmt 字符串,一个是argsObject数组(保存着所有的参数,如果调用者提供的是整型等基本类型,自动打包功能将它们自动打包成对应的对象类型),方法处理的时候,解析字符串中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)  利用运行时的反射调试程序;Fieldget方法可以获取运行时的值,但是当Field是私有时,Java安全机制不允许方法, 为了达到目的,JavaField MethodConstructor类对象有setAccessible(true)对这三类的对象授权;

10)    反射机制用来创建泛型数组,对于Object[]数组作参数,当在进行数组拷贝的时候,由于不知道数组存放的真实类型,可以利用反射机制。

11)    方法指针,虽然Java语言中没有方法指针,但是反射包中却有此用法,Methodinvoke方法就是通过对象的方法作为参数,执行对象的方法,具体参考API

6、  总结

1)  将公共操作和域放在超类中;

2)  不要使用protected修饰域;

3)  使用继承实现”is-a”关系,但是不可滥用,一定要分析清楚超类的域和操作在子类使用使用;

4)  除非所有的继承方法都有意义,否则不要使用继承;

5)  在覆盖方法时,不要改变预期的行为;

6)  使用多态,而不是类型信息;

7)  不要过多使用反射,反射很脆弱,通常会出现一些编译器很难帮助程序员发现的错误;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值