标签:style blog http java color 使用 os strong
看到了这篇关于Java到底哪里出了问题的文章,笑傻了23333
“Java developers just can’t help themselves it seems - give em an inch, and next thing you know you’re looking at a OO hierarchy 15 layers deep and instantiating a hammer hammer factory.”
父类的数组或是变量可以放子类的引用,比如
SuperClass[] a = new SuperClass[10]; a[0] = new SubClass();
这样就可以得到多态了。在Java里会默认使用dynamic binding,和C++那种需要特意指明virtual才能启用的做法相反。
Java支持父类和子类数组之间的赋值,你可以
Subclass[] suba = new Subclass[10]; Superclass[] supa = suba;
把一整个数组赋值,底层实际上还是同一个引用,Java会记得这个数组最开始是什么类的,所以如果你想趁着这个数组现在表面上是父类,想拿一个父类对象塞进去的话
supa[0] = new SuperClass();
会报ArrayStoreException(因为Superclass is not a Subclass, 这样干和 suba[0] = new SuperClass() 没区别)
子类放进父类可以直接放
sup = sub;
而父类放进子类呢?可能可以,只要它一开始是这个子类,可以被cast回来。Java对象的cast语法上像是C原生的static cast,但实际上原理和C++的dynamic_cast才是一路的:
sub2 = (SubClass) sup;
注意这里一定要做cast,不能直接赋值回去,因为编译器会检查你是否promise too much,直接赋值(sub2 = sup)就是这样一种表现。如果你做了cast(且cast的类型和引用类型存在继承关系),检查会推迟到运行时,如果运行时检查出实际类型不能被cast回来,才会报ClassCastException(C++不能cast的时候是返回null而已)。
为了防止ClassCastException挂掉整个程序,如果选择不为这个exception加handler,一般会在cast前先用instanceof检查是否可以cast
if (sup instanceof SubClass) { sub2 = (SubClass) sup; }
abstract class的不能实例化指的是不能和new一起用而已,但是可以用来声明变量
AbClass a; // OK! AbClass a = new AbClass(); // Go to hell! AbClass a = new NonAbSubClassOfAbClass(); // OK
注意 equals 的参数是 Object,在子类里override的时候也是这个,所以声明是
public boolean equals(Object obj) {...}
实现equals的基本步骤
声明为
public boolean equals(Object obj) {...}
这里参数类型不能替换成其他,换了就signature和Object的equals就不同了,不是override而是添加新的方法。
首先检查是否为同一个对象,因为检查引用位置的开销比较低
if (this == obj) return true;
检查obj是否为null
if (obj == null) return false;
检查类,按照前面说的子类和父类对相等的定义是否相同来决定怎么写
子类的相等定义和父类不同,那么两者必须同类
if (getClass() != obj.getClass()) return false;
相等的定义已经在父类确定,那么这就是父类里final的equals,另一个对象需要至少是这个类的子类
if (!(obj instanceof ClassName)) return false;
注意,如果子类的相等定义和父类不同,也就是用getClass的情形,那么在equals的第一句通常还要写上
if (!super.equals(obj)) return false;
确保cast之后在父类的level上相同。
String的hashCode是
s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
(和我当年写的一个hash函数好像啊= =!)参见String的API
Object自带的toString返回的是
getClass().getName() + ‘@‘ + Integer.toHexString(hashCode())
一般toString返回的格式是
package.class[field1=a,field2=b,...]
写法
ArrayList<T> a = new ArrayList<T>();
右边的T可以安全地省略,因为编译器发现找不到参数会去看左边。
数组和ArrayList的转换用Arrays.asList和toArray
T[] a1 = new T[10]; ArrayList<T> a2 = new ArrayList<T>(Arrays.asList(a1)); T[] a3 = new T[a2.size()]; a2.toArray(a3);
泛型的类型参数不能是原始类型,需要用原始类型的wrapper : int对应Integer,double对应Double, .etc
ArrayList<int> a; // WRONG ArrayList<Integer> a; // OK
声明方法类似于
public enum Name {ENUM1, ENUM2, ...};
enum的类型可以有自己的field,方法,构造函数
public enum Name { ENUM1, ENUM2, ... ; private int field ...; private Name(...) {...} }
名字与enum的转换
Name.ENUM1.toString(); // "ENUM1" Enum.valueOf(Name.class, "ENUM2"); // enum with type ENUM2
用polymorphism而不是type polymorphism,举例来说,当你看到
if (x is of typeA) action1(x) else if (x is of typeB) action2(x)
如果action1和action2的behavior存在重叠,最好重新考虑是否设计一个公共的父类或者interface,用多态来避开这种if-else test
标签:style blog http java color 使用 os strong
原文地址:http://www.cnblogs.com/joyeecheung/p/3869021.html