Java集合类库的顶层里的Collection,List,Set是抽象类的话是否更“正确”一些?
不正确,java是单继承的,如果顶层是抽象类,对于后面的代码扩展很不利的。而java的接口是多实现的,java官方对于Collection和set、List设计的也都是接口来设计,符合了java的接口多少实现的特性。如果都是设计成抽象类,后面我们在实际开发中,自己的类就没法实现了。具体它们的结构如下:
Collection 接口的接口 对象的集合(单列集合)
├——-List 接口:元素按进入先后有序保存,可重复
│—————-├ LinkedList 接口实现类, 链表, 插入删除, 没有同步, 线程不安全
│—————-├ ArrayList 接口实现类, 数组, 随机访问, 没有同步, 线程不安全
│—————-└ Vector 接口实现类 数组, 同步, 线程安全
│ ———————-└ Stack 是Vector类的实现类
└——-Set 接口: 仅接收一次,不可重复,并做内部排序
├—————-└HashSet 使用hash表(数组)存储元素
│————————└ LinkedHashSet 链表维护元素的插入次序
└ —————-TreeSet 底层实现为二叉树,元素排好序
Java中的类,成员变量的值,在声明的时候直接赋值与在构造函数中再赋值,这个是无所谓的,还是有什么规矩?
声明的时候,不管你是否赋值,不同的类型(Build-in的基本类型和Class)都有缺省的值,比如int就是0,Object就是null.
所以,如果没有特别的初始赋值,不用在构造函数里去初始化properties / Fields,加重对象创建时无谓的负担;换言之,如果在对象创建时期没有特别的初始化要求,缺省构造函数也不不用写,JVM自己知道处理。
显示的构造函数自有其使用的场合。它给你提供了一种时机,在对象被创建的时候做一些定制化的、初始化的工作。举个例子,比如你的class里有个成员是:
private List<Member> memebers;
你想统一一下getMembers()的行为,也就是说,不管有没有member,都返回一个List对象,而不是时而为null,时而为List<Member>,给Caller添麻烦。
那么就在构造函数里解决这个问题,加一行代码比如:
this.members = new ArrayList<Member>();
这样子,即便这个对象刚刚被new出来,在上面调用getMembers也不会返回null。

