1.identifier
以_、$、number开头
int $i = 10;
还可以用unicode
String /u4e00 = "abc";
float f/u4e01 = 1.1f;
enum作为关键字,从jdk1.5开始不允许作为identifier
非法:int e#;
2. java bean spec
getter setter必须为pubilc
对于listener,对应AddSomeListener,removeSomeListener
//Examples of invalid JavaBean method signatures are void setCustomerName(String s) // must be public public void modifyMyValue(int v) // can't use 'modify' public void addXListener(MyListener m) // listener type mismatch
3. Interface, abstract
Interface methods must not be static
Interface methods can only be public, abstract (protected is not allowed but is legal for abstract method in abstract class)
abstract methods can not be marked final, strictfp, native
4. method override
override的method,子类不能抛出比父类更大、更多的exception,可以不抛异常,
unchecked (runtime)exception不受约束
class Base{ void test(){ try{ foo(); foo2(); }catch(Exception e){ System.out.println("exception -> foo()"); } } protected void foo() throws java.io.IOException{ System.out.println("Base:foo()"); } void foo2() throws Exception{ System.out.println("Base:foo2()"); } public static void main(String args[]){ Base b = new Sub(); b.test(); //output: //Sub:foo() //Sub:foo2() } } class Sub extends Base{ // java.io.FileNotFOundExcetion -> java.io.IOException public void foo() throws java.io.FileNotFoundException{ System.out.println("Sub:foo()"); } // throws no checked Exception but unchecked one (RuntimeException) public void foo2() throws RuntimeException{ System.out.println("Sub:foo2()"); } }
父类的private的方法将不会被override, 子类的同名方法仅被看作一个普通方法
class Base { void test() { foo(); } // private private void foo() { System.out.println("Base:foo()"); } public static void main(String args[]) { Base b = new Sub(); b.test(); // output: // Base:foo() } } class Sub extends Base { // just a common method, no overridding public void foo() { System.out.println("Sub:foo()"); } }
声明父类的应用到子类的instance,父类的方法会被assumed called,尽管实际上调用的是子类override的方法
所以调用要符合父类方法的声明特点,比如异常捕获等。
class A{ public void test()throws Exception{ throw new Exception("A.test() exception"); } public static void main(String...strings){ A a= new B(); //a.test(); //unhandled exception //It is assumed super version of method test (A.test()) be called //although B.test() be called actually. B b = new B(); b.test();//it's ok, it's assumed B.test() be called } } class B extends A{ public void test(){ } }
从JDK1.5开始,override时,返回类型为父类返回类型的子类时也合法
用1.4编译 javac -source 1.4 Base.java 将得到编译错误(imcompatible return type)
class Base { public A f(){ System.out.println("A"); return null; } public static void main(String args[]) { Base b = new Sub(); b.f(); //output: //B } } class Sub extends Base{ public B f(){ System.out.println("B"); return null; } } class A{} class B extends A{}
声明为final的method不能被override,但是一旦同时声明为private,对子类来说是hidden的,所以可以redefine一样的方法,只不过这里不是override
public class Base { public void test(){ foo(); } // declared as private, final private final void foo(){ System.out.println("Base:foo()"); } } class Sub extends Base{ // no compile error, Base:foo is hidden, no final method override here public final void foo(){ System.out.println("Sub:foo()"); } public static void main(String args[]){ Base b = new Sub(); b.test(); //output //Base:foo() } }
5. protected
protected 的可见是通过inheritance,而不是在子类直接操作父类的reference
package scjp.pkg1; public class Base { protected int value = 10; protected void foo() { System.out.println("Base:foo()"); } }
package scjp.pkg2; import scjp.pkg1.Base; public class Sub extends Base { Base base = new Base(); public void subFoo() { foo(); // OK to access protected method through inheritance // compile error, protected variable not visible through reference //System.out.println(base.value); } }
package scjp.pkg2; //same package with class Sub public class Sub2 { Sub s = new Sub(); { // Base.value is not visible through reference //System.out.println(s.value); System.out.println(s.aaa); } }
6. 可变参数
public class Demo { public static void main(String ...args) {// <--> String args[] test1(new String[]{"a","b"}); } public static void test1(String... strs){ for (String str:strs){ System.out.println(str); } } public static void test2(int a, String...strings){} // illegal: //public static void test2(String...strings, int a){} //public static void test2(String...strings, String...strings2){} }
overload时,可变参数的method会是最后的选择
public class Base { void test(Base[]...bs){ System.out.println("Base[]...bs"); } void test(Object o){ System.out.println("Object o"); } public static void main(String args[]){ Base[] a = new Base[3]; //var-para overload method will be the last chosen one new Base().test(a); //output //Object o } }
7. enum
enum可看做特殊的java class,具体参见另一篇java里的enum
所以语法跟class类似
8. interface可以extends多个interface
interface I1{} interface I2{} interface I3 extends I1, I2{ //no compile error }
9. overload
除了parameter list是必须要不同的之外,其他的return type, exception 声明, 访问权限(public,private...)都是任意的
父类、子类分别作为参数列表是合法的overload
overload是compile time确定的,所以由reference type决定,而不是object type,
override是runtime的,由object type决定,而不是reference type
class Animal { } class Horse extends Animal { } class UseAnimals { public void doStuff(Animal a) { System.out.println("In the Animal version"); } public void doStuff(Horse h) { System.out.println("In the Horse version"); } public static void main(String[] args) { UseAnimals ua = new UseAnimals(); Animal animalObj = new Animal(); Horse horseObj = new Horse(); Animal hObj = new Horse(); ua.doStuff(animalObj); ua.doStuff(horseObj); ua.doStuff(hObj); // Attention! //output: //In the Animal version //In the Horse version //In the Animal version } }
10. constructor
抽象类可以有constructor,但interface不允许,interface不是一个类,只是定义一些规则而已,所以没有构造的意义,这个不同于抽象类
interface I{ //compile error! //Interfaces cannot have constructors //public I(){}; } abstract class Base implements I{ public Base(){ System.out.println("Base.constructor"); } } class Sub extends Base{ public Sub(){ System.out.println("Sub.constructor"); } public static void main(String...strings){ new Sub(); //output: //Base.constructor //Sub.constructor } }
11. operators
+=, -= , *=, /=包含有隐式转换
a+=b 不等价于 a=a+b
byte b = 3; // implicit cast int to byte b += 128; // ok, b = (byte)(b+128) //b = b+128;// error, can not convert int to byte
to be continued...