Loading

Java中一些常被忽视的特性

[原文链接]

说明:

1 参考自stackoverflow上的一个帖子以及广大网友的回复: http://stackoverflow.com/questions/15496/hidden-features-of-java?page=4&tab=votes#tab-top

2 在这些回复中,我选择了一些写到这篇博客中,当然也有很多回复我认为没有必要翻译出来.

3 在翻译的过程中,为了快速完成,主要把代码贴过来,只要是对Java比较熟悉的, 看到代码基本上就能理解这个特性.对其他解释性的文字翻译的比较少, 如果感兴趣可以查看原文, 原文地址在上面已经给出.

正文:

1 使用Class<T>进行运行时类型检查

如果一个实例是根据配置文件中的类型创建出来的, 那么在代码中并不能明确确定该实例的类型,使用该方法可以在运行时检查类型
  1. public interface SomeInterface {  
  2.   void doSomething(Object o);  
  3. }  
  4. public abstract class RuntimeCheckingTemplate<T> {  
  5.   private Class<T> clazz;  
  6.   protected RuntimeChecking(Class<T> clazz) {  
  7.     this.clazz = clazz;  
  8.   }  
  9.   
  10.   public void doSomething(Object o) {  
  11.     if (clazz.isInstance(o)) {  
  12.       doSomethingWithGeneric(clazz.cast(o));  
  13.     } else {  
  14.       // log it, do something by default, throw an exception, etc.  
  15.     }  
  16.   }  
  17.   
  18.   protected abstract void doSomethingWithGeneric(T t);  
  19. }  
  20.   
  21. public class ClassThatWorksWithStrings extends RuntimeCheckingTemplate<String> {  
  22.   public ClassThatWorksWithStrings() {  
  23.      super(String.class);  
  24.   }  
  25.   
  26.   protected abstract void doSomethingWithGeneric(T t) {  
  27.     // Do something with the generic and know that a runtime exception won't occur   
  28.     // because of a wrong type  
  29.   }  
  30. }  
public interface SomeInterface {
  void doSomething(Object o);
}
public abstract class RuntimeCheckingTemplate<T> {
  private Class<T> clazz;
  protected RuntimeChecking(Class<T> clazz) {
    this.clazz = clazz;
  }

  public void doSomething(Object o) {
    if (clazz.isInstance(o)) {
      doSomethingWithGeneric(clazz.cast(o));
    } else {
      // log it, do something by default, throw an exception, etc.
    }
  }

  protected abstract void doSomethingWithGeneric(T t);
}

public class ClassThatWorksWithStrings extends RuntimeCheckingTemplate<String> {
  public ClassThatWorksWithStrings() {
     super(String.class);
  }

  protected abstract void doSomethingWithGeneric(T t) {
    // Do something with the generic and know that a runtime exception won't occur 
    // because of a wrong type
  }
}

2 整数自动装箱

  1. Integer a = 1;  
  2. Integer b = 1;  
  3. Integer c = new Integer(1);  
  4. Integer d = new Integer(1);  
  5.   
  6. Integer e = 128;  
  7. Integer f = 128;  
  8.   
  9. assertTrue (a == b);   // again: this is true!  
  10. assertFalse(e == f); // again: this is false!  
  11. assertFalse(c == d);   // again: this is false!  
Integer a = 1;
Integer b = 1;
Integer c = new Integer(1);
Integer d = new Integer(1);

Integer e = 128;
Integer f = 128;

assertTrue (a == b);   // again: this is true!
assertFalse(e == f); // again: this is false!
assertFalse(c == d);   // again: this is false!

3 格式化字符串

  1. String w = "world";  
  2. String s = String.format("Hello %s %d", w, 3);  
String w = "world";
String s = String.format("Hello %s %d", w, 3);

4 匿名内部类中可以访问final类型的局部变量

  1. final String foo = "42";  
  2. new Thread() {  
  3.     public void run() {  
  4.          dowhatever(foo);  
  5.     }  
  6. }.start();  
    final String foo = "42";
    new Thread() {
        public void run() {
             dowhatever(foo);
        }
    }.start();

5 数组类型的对象调用clone方法可以复制一个数组

  1. int[] arr = {123};  
  2. int[] arr2 = arr.clone();  
int[] arr = {1, 2, 3};
int[] arr2 = arr.clone();

6 通过反射可以访问私有成员

  1. public class Foo {  
  2.     private int bar;  
  3.   
  4.     public Foo() {  
  5.         setBar(17);  
  6.     }  
  7.   
  8.     private void setBar(int bar) {  
  9.         this.bar=bar;  
  10.     }  
  11.   
  12.     public int getBar() {  
  13.         return bar;  
  14.     }  
  15.   
  16.     public String toString() {  
  17.         return "Foo[bar="+bar+"]";  
  18.     }  
  19. }  
public class Foo {
    private int bar;

    public Foo() {
        setBar(17);
    }

    private void setBar(int bar) {
        this.bar=bar;
    }

    public int getBar() {
        return bar;
    }

    public String toString() {
        return "Foo[bar="+bar+"]";
    }
}
  1. import java.lang.reflect.*;  
  2.   
  3. public class AccessibleExample {  
  4.     public static void main(String[] args)  
  5.         throws NoSuchMethodException,IllegalAccessException, InvocationTargetException, NoSuchFieldException {  
  6.         Foo foo=new Foo();  
  7.         System.out.println(foo);  
  8.   
  9.         Method method=Foo.class.getDeclaredMethod("setBar"int.class);  
  10.         method.setAccessible(true);  
  11.         method.invoke(foo, 42);  
  12.   
  13.         System.out.println(foo);  
  14.         Field field=Foo.class.getDeclaredField("bar");  
  15.         field.setAccessible(true);  
  16.         field.set(foo, 23);  
  17.         System.out.println(foo);  
  18.     }  
  19. }  
import java.lang.reflect.*;

public class AccessibleExample {
    public static void main(String[] args)
        throws NoSuchMethodException,IllegalAccessException, InvocationTargetException, NoSuchFieldException {
        Foo foo=new Foo();
        System.out.println(foo);

        Method method=Foo.class.getDeclaredMethod("setBar", int.class);
        method.setAccessible(true);
        method.invoke(foo, 42);

        System.out.println(foo);
        Field field=Foo.class.getDeclaredField("bar");
        field.setAccessible(true);
        field.set(foo, 23);
        System.out.println(foo);
    }
}
打印结果:
  1. Foo[bar=17]  
  2. Foo[bar=42]  
  3. Foo[bar=23]  
Foo[bar=17]
Foo[bar=42]
Foo[bar=23]

7 使用Scanner解析字符串

  1. String input = "1 fish 2 fish red fish blue fish";  
  2. Scanner s = new Scanner(input).useDelimiter("\\s*fish\\s*");  
  3. System.out.println(s.nextInt());  
  4. System.out.println(s.nextInt());  
  5. System.out.println(s.next());  
  6. System.out.println(s.next());  
  7. s.close();  
String input = "1 fish 2 fish red fish blue fish";
Scanner s = new Scanner(input).useDelimiter("\\s*fish\\s*");
System.out.println(s.nextInt());
System.out.println(s.nextInt());
System.out.println(s.next());
System.out.println(s.next());
s.close();

8 可以使用非英文给标示符命名

  1. String Überschrift="";  
String Überschrift="";
译者注: 中文也可以.
 

9 访问局部变量比访问成员变量快

  1. public class Slow {  
  2.   /** Loop counter; initialized to 0. */  
  3.   private long i;  
  4.   
  5.   public static void main( String args[] ) {  
  6.     Slow slow = new Slow();  
  7.   
  8.     slow.run();  
  9.   }  
  10.   
  11.   private void run() {  
  12.     while( i++ < 10000000000L )  
  13.       ;  
  14.   }  
  15. }  
public class Slow {
  /** Loop counter; initialized to 0. */
  private long i;

  public static void main( String args[] ) {
    Slow slow = new Slow();

    slow.run();
  }

  private void run() {
    while( i++ < 10000000000L )
      ;
  }
}
以上代码平均耗时18.018s
 
优化后的代码:
  1. public class Fast {  
  2.   /** Loop counter; initialized to 0. */  
  3.   private long i;  
  4.   
  5.   public static void main( String args[] ) {  
  6.     Fast fast = new Fast();  
  7.   
  8.     fast.run();  
  9.   }  
  10.   
  11.   private void run() {  
  12.     long i = getI();  
  13.   
  14.     while( i++ < 10000000000L )  
  15.       ;  
  16.   
  17.     setI( i );  
  18.   }  
  19.   
  20.   private long setI( long i ) {  
  21.     this.i = i;  
  22.   }  
  23.   
  24.   private long getI() {  
  25.     return this.i;  
  26.   }  
  27. }  
public class Fast {
  /** Loop counter; initialized to 0. */
  private long i;

  public static void main( String args[] ) {
    Fast fast = new Fast();

    fast.run();
  }

  private void run() {
    long i = getI();

    while( i++ < 10000000000L )
      ;

    setI( i );
  }

  private long setI( long i ) {
    this.i = i;
  }

  private long getI() {
    return this.i;
  }
}
以上代码平均耗时10.509s
 

10 const是一个关键字, 但是你不能使用它

  1. int const = 1;   // "not a statement"  
  2. const int i = 1// "illegal start of expression"  
int const = 1;   // "not a statement"
const int i = 1; // "illegal start of expression"

11 C风格的打印语句

  1. System.out.printf("%d %f %.4f"3,Math.E,Math.E);  
System.out.printf("%d %f %.4f", 3,Math.E,Math.E);

12 匿名内部类可以直接调用子类中定义的方法

  1. (new Object() {  
  2.     public String someMethod(){   
  3.         return "some value";  
  4.     }  
  5. }).someMethod();  
(new Object() {
    public String someMethod(){ 
        return "some value";
    }
}).someMethod();
  1. new Object() {  
  2.   void foo(String s) {  
  3.     System.out.println(s);  
  4.   }  
  5. }.foo("Hello");  
new Object() {
  void foo(String s) {
    System.out.println(s);
  }
}.foo("Hello");
尽管创建的匿名内部类实例并没有实现一个独立的接口, 但是能直接调用不在父类Object中的方法

13 List.subList()创建原有list的一个视图

操作一个list的一部分, 并且对subList的修改会反映到原有list中
  1. list.subList(from, to).clear();  
list.subList(from, to).clear();
以上代码删除原有list中从from到to位置的元素.
 
译者注: 可查看jdk中ArrayList的源码来验证这一结论.下面贴出部分源码:
  1. public List<E> subList(int fromIndex, int toIndex) {  
  2.         subListRangeCheck(fromIndex, toIndex, size);  
  3.         return new SubList(this0, fromIndex, toIndex);  
  4.     }  
public List<E> subList(int fromIndex, int toIndex) {
        subListRangeCheck(fromIndex, toIndex, size);
        return new SubList(this, 0, fromIndex, toIndex);
    }
 
SubList作为ArrayList的一个内部类:
  1. private class SubList extends AbstractList<E> implements RandomAccess {  
  2.         private final AbstractList<E> parent;  
  3.         private final int parentOffset;  
  4.         private final int offset;  
  5.         int size;  
  6.   
  7.         SubList(AbstractList<E> parent,  
  8.                 int offset, int fromIndex, int toIndex) {  
  9.             this.parent = parent;  
  10.             this.parentOffset = fromIndex;  
  11.             this.offset = offset + fromIndex;  
  12.             this.size = toIndex - fromIndex;  
  13.             this.modCount = ArrayList.this.modCount;  
  14.         }  
  15. // ......  
  16.   
  17.         public void add(int index, E e) {  
  18.             rangeCheckForAdd(index);  
  19.             checkForComodification();  
  20.             parent.add(parentOffset + index, e);  
  21.             this.modCount = parent.modCount;  
  22.             this.size++;  
  23.         }  
  24.   
  25.         public E remove(int index) {  
  26.             rangeCheck(index);  
  27.             checkForComodification();  
  28.             E result = parent.remove(parentOffset + index);  
  29.             this.modCount = parent.modCount;  
  30.             this.size--;  
  31.             return result;  
  32.         }  
  33.   
  34. // ......  
private class SubList extends AbstractList<E> implements RandomAccess {
        private final AbstractList<E> parent;
        private final int parentOffset;
        private final int offset;
        int size;

        SubList(AbstractList<E> parent,
                int offset, int fromIndex, int toIndex) {
            this.parent = parent;
            this.parentOffset = fromIndex;
            this.offset = offset + fromIndex;
            this.size = toIndex - fromIndex;
            this.modCount = ArrayList.this.modCount;
        }
// ......

        public void add(int index, E e) {
            rangeCheckForAdd(index);
            checkForComodification();
            parent.add(parentOffset + index, e);
            this.modCount = parent.modCount;
            this.size++;
        }

        public E remove(int index) {
            rangeCheck(index);
            checkForComodification();
            E result = parent.remove(parentOffset + index);
            this.modCount = parent.modCount;
            this.size--;
            return result;
        }

// ......
从add和remove方法可以看出, 对subList的修改反映到了原有list(parent)中.
 

14 自限定泛型

  1. class SelfBounded<T extends SelfBounded<T>> {  
  2. }  
class SelfBounded<T extends SelfBounded<T>> {
}

15 可以在方法中定义一个内部类

  1. public Foo foo(String in) {  
  2.     class FooFormat extends Format {  
  3.         public Object parse(String s, ParsePosition pp) { // parse stuff }  
  4.     }  
  5.     return (Foo) new FooFormat().parse(in);  
  6.   
  7. }  
public Foo foo(String in) {
    class FooFormat extends Format {
        public Object parse(String s, ParsePosition pp) { // parse stuff }
    }
    return (Foo) new FooFormat().parse(in);

}

16 Java中可以使用标号

  1. public int aMethod(){  
  2.     http://www.google.com  
  3.     return 1;  
  4. }  
public int aMethod(){
    http://www.google.com
    return 1;
}
上面的http:是一个标号, //是注释
 

17 没有main方法的HelloWorld

  1. public class WithoutMain {  
  2.     static {  
  3.         System.out.println("Look ma, no main!!");  
  4.         System.exit(0);  
  5.     }  
  6. }  
public class WithoutMain {
    static {
        System.out.println("Look ma, no main!!");
        System.exit(0);
    }
}
运行结果:
  1. $ java WithoutMain  
  2. Look ma, no main!!  
$ java WithoutMain
Look ma, no main!!

18 Shutdown钩子

在虚拟机停掉之前被调用:
  1. Runtime.getRuntime().addShutdownHook(new Thread() {  
  2.                   public void run() {  
  3.                       endApp();  
  4.                   }  
  5.             });;  
Runtime.getRuntime().addShutdownHook(new Thread() {
                  public void run() {
                      endApp();
                  }
            });;

19 URL类的equals方法

  1. new URL("http://www.yahoo.com").equals(new URL("http://209.191.93.52"))  
new URL("http://www.yahoo.com").equals(new URL("http://209.191.93.52"))
上述代码结果为true
 

20 在没有声明抛出任何异常的方法中抛出受检查异常

  1. import java.rmi.RemoteException;  
  2.   
  3. class Thrower {  
  4.     public static void spit(final Throwable exception) {  
  5.         class EvilThrower<T extends Throwable> {  
  6.             @SuppressWarnings("unchecked")  
  7.             private void sneakyThrow(Throwable exception) throws T {  
  8.                 throw (T) exception;  
  9.             }  
  10.         }  
  11.         new EvilThrower<RuntimeException>().sneakyThrow(exception);  
  12.     }  
  13. }  
  14.   
  15. public class ThrowerSample {  
  16.     public static void main( String[] args ) {  
  17.         Thrower.spit(new RemoteException("go unchecked!"));  
  18.     }  
  19. }  
import java.rmi.RemoteException;

class Thrower {
    public static void spit(final Throwable exception) {
        class EvilThrower<T extends Throwable> {
            @SuppressWarnings("unchecked")
            private void sneakyThrow(Throwable exception) throws T {
                throw (T) exception;
            }
        }
        new EvilThrower<RuntimeException>().sneakyThrow(exception);
    }
}

public class ThrowerSample {
    public static void main( String[] args ) {
        Thrower.spit(new RemoteException("go unchecked!"));
    }
}

21 可以抛出null

  1. public static void main(String[] args) {  
  2.      throw null;  
  3. }  
public static void main(String[] args) {
     throw null;
}

22 自动装箱中的一些规则

  1. Long value = new Long(0);  
  2.         System.out.println(value.equals(0));  //false  
  3.           
  4.         Integer i = 0;  
  5.         System.out.println(i.equals(0));     //true  
  6.           
  7.         Integer j = new Integer(0);  
  8.         System.out.println(j.equals(0));    //true  
  9.         System.out.println(j.equals(i));    //true  
  10.         System.out.println(i == j);         //false  
  11.           
  12.         Integer m = 0;  
  13.         System.out.println(i.equals(m));    //true  
  14.         System.out.println(i == m);         //true  
  15.           
  16.         Integer x = 128;  
  17.         Integer y = 128;  
  18.         Integer z = new Integer(128);  
  19.         System.out.println(x.equals(y));    //true  
  20.         System.out.println(x == y);         //fasle  
  21.         System.out.println(x.equals(z));    //true  
  22.         System.out.println(x == z);     //false  
Long value = new Long(0);
		System.out.println(value.equals(0));  //false
		
		Integer i = 0;
		System.out.println(i.equals(0));     //true
		
		Integer j = new Integer(0);
		System.out.println(j.equals(0));	//true
		System.out.println(j.equals(i));	//true
		System.out.println(i == j);			//false
		
		Integer m = 0;
		System.out.println(i.equals(m));	//true
		System.out.println(i == m);			//true
		
		Integer x = 128;
		Integer y = 128;
		Integer z = new Integer(128);
		System.out.println(x.equals(y));	//true
		System.out.println(x == y);			//fasle
		System.out.println(x.equals(z));	//true
		System.out.println(x == z);		//false

23 在finally块中返回

  1. @SuppressWarnings("finally")  
  2. public static int returnSomething() {  
  3.     try {  
  4.         throw new RuntimeException("foo!");  
  5.     } finally {  
  6.         return 1;  
  7.     }  
  8.       
  9.     //在这里可以不写return语句  
  10. }  
  11.   
  12. public static void main(String[] args) {  
  13.     System.out.println(returnSomething());   // 返回1  
  14. }  
	@SuppressWarnings("finally")
	public static int returnSomething() {
	    try {
	        throw new RuntimeException("foo!");
	    } finally {
	        return 1;
	    }
	    
	    //在这里可以不写return语句
	}
	
	public static void main(String[] args) {
		System.out.println(returnSomething());   // 返回1
	}

24 数组初始化的误区

以下代码是正确的:
  1. public class Foo {  
  2.     public void doSomething(String[] arg) {}  
  3.   
  4.     public void example() {  
  5.         String[] strings = { "foo""bar" };  
  6.         doSomething(strings);  
  7.     }  
  8. }  
public class Foo {
    public void doSomething(String[] arg) {}

    public void example() {
        String[] strings = { "foo", "bar" };
        doSomething(strings);
    }
}
而以下代码是错误的:
  1. public class Foo {  
  2.   
  3.     public void doSomething(String[] arg) {}  
  4.   
  5.     public void example() {  
  6.         doSomething({ "foo""bar" });  
  7.     }  
  8. }  
public class Foo {

    public void doSomething(String[] arg) {}

    public void example() {
        doSomething({ "foo", "bar" });
    }
}

25 内部类中使用this访问外部类成员

  1. import java.util.Comparator;  
  2.   
  3. public class ContainerClass {  
  4. boolean sortAscending;  
  5. public Comparator createComparator(final boolean sortAscending){  
  6.     Comparator comparator = new Comparator<Integer>() {  
  7.   
  8.         public int compare(Integer o1, Integer o2) {  
  9.             if (sortAscending || ContainerClass.this.sortAscending) {  
  10.                 return o1 - o2;  
  11.             } else {  
  12.                 return o2 - o1;  
  13.             }  
  14.         }  
  15.   
  16.     };  
  17.     return comparator;  
  18. }  
  19. }  
import java.util.Comparator;

public class ContainerClass {
boolean sortAscending;
public Comparator createComparator(final boolean sortAscending){
	Comparator comparator = new Comparator<Integer>() {

		public int compare(Integer o1, Integer o2) {
			if (sortAscending || ContainerClass.this.sortAscending) {
				return o1 - o2;
			} else {
				return o2 - o1;
			}
		}

	};
	return comparator;
}
}

26 final局部变量可以不再声明的同时初始化

  1. public Object getElementAt(int index) {  
  2.     final Object element;  
  3.     if (index == 0) {  
  4.          element = "Result 1";  
  5.     } else if (index == 1) {  
  6.          element = "Result 2";  
  7.     } else {  
  8.          element = "Result 3";  
  9.     }  
  10.     return element;  
  11. }  
public Object getElementAt(int index) {
    final Object element;
    if (index == 0) {
         element = "Result 1";
    } else if (index == 1) {
         element = "Result 2";
    } else {
         element = "Result 3";
    }
    return element;
}

27 使用初始化块快速创建对象

  1. Map map = new HashMap() {{  
  2.     put("a key""a value");  
  3.     put("another key""another value");  
  4. }};  
Map map = new HashMap() {{
    put("a key", "a value");
    put("another key", "another value");
}};
  1. JFrame frame = new JFrame(){{  
  2.          add( new JPanel(){{  
  3.                add( new JLabel("Hey there"){{   
  4.                     setBackground(Color.black);  
  5.                     setForeground( Color.white);  
  6.                 }});  
  7.   
  8.                 add( new JButton("Ok"){{  
  9.                     addActionListener( new ActionListener(){  
  10.                         public void actionPerformed( ActionEvent ae ){  
  11.                             System.out.println("Button pushed");  
  12.                         }  
  13.                      });  
  14.                  }});  
  15.         }});  
  16.     }};  
JFrame frame = new JFrame(){{
         add( new JPanel(){{
               add( new JLabel("Hey there"){{ 
                    setBackground(Color.black);
                    setForeground( Color.white);
                }});

                add( new JButton("Ok"){{
                    addActionListener( new ActionListener(){
                        public void actionPerformed( ActionEvent ae ){
                            System.out.println("Button pushed");
                        }
                     });
                 }});
        }});
    }};

28 java1.5中引入可变参数

  1. public void foo(String... bars) {  
  2.    for (String bar: bars)  
  3.       System.out.println(bar);  
  4. }  
public void foo(String... bars) {
   for (String bar: bars)
      System.out.println(bar);
}

29 枚举可以实现一个接口

  1. public interface Room {  
  2.    public Room north();  
  3.    public Room south();  
  4.    public Room east();  
  5.    public Room west();  
  6. }  
  7.   
  8. public enum Rooms implements Room {  
  9.    FIRST {  
  10.       public Room north() {  
  11.          return SECOND;  
  12.       }  
  13.    },  
  14.    SECOND {  
  15.       public Room south() {  
  16.          return FIRST;  
  17.       }  
  18.    }  
  19.   
  20.    public Room north() { return null; }  
  21.    public Room south() { return null; }  
  22.    public Room east() { return null; }  
  23.    public Room west() { return null; }  
  24. }  
public interface Room {
   public Room north();
   public Room south();
   public Room east();
   public Room west();
}

public enum Rooms implements Room {
   FIRST {
      public Room north() {
         return SECOND;
      }
   },
   SECOND {
      public Room south() {
         return FIRST;
      }
   }

   public Room north() { return null; }
   public Room south() { return null; }
   public Room east() { return null; }
   public Room west() { return null; }
}

30 泛型方法可以显示指定类型参数

  1. Collections.<String,Integer>emptyMap()  
Collections.<String,Integer>emptyMap()

31 枚举中可以有构造方法和普通方法

  1. enum Cats {  
  2.   FELIX(2), SHEEBA(3), RUFUS(7);  
  3.   
  4.   private int mAge;  
  5.   Cats(int age) {  
  6.     mAge = age;  
  7.   }  
  8.   public int getAge() {  
  9.     return mAge;  
  10.    }  
  11. }  
enum Cats {
  FELIX(2), SHEEBA(3), RUFUS(7);

  private int mAge;
  Cats(int age) {
    mAge = age;
  }
  public int getAge() {
    return mAge;
   }
}

32 finally块中的return语句阻止try中异常的抛出

  1. public static void doSomething() {  
  2.     try {  
  3.       //Normally you would have code that doesn't explicitly appear   
  4.       //to throw exceptions so it would be harder to see the problem.  
  5.       throw new RuntimeException();  
  6.     } finally {  
  7.       return;  
  8.     }  
  9.   }  
public static void doSomething() {
    try {
      //Normally you would have code that doesn't explicitly appear 
      //to throw exceptions so it would be harder to see the problem.
      throw new RuntimeException();
    } finally {
      return;
    }
  }

33 instanceof关键字不用判断null

  1. ifnull != aObject && aObject instanceof String )  
  2. {  
  3.     ...  
  4. }  
if( null != aObject && aObject instanceof String )
{
    ...
}
可以使用以下代码代替(不用判断null)
  1. if( aObject instanceof String )  
  2. {  
  3.     ...  
  4. }  
if( aObject instanceof String )
{
    ...
}

34 java1.5中引入的协变返回类型

如果子类覆盖了父类的方法, 子类中的方法可以返回父类中方法的返回值类型或其子类型
  1. class Souper {  
  2.     Collection<String> values() {  
  3.         ...  
  4.     }  
  5. }  
  6.   
  7. class ThreadSafeSortedSub extends Souper {  
  8.     @Override  
  9.     ConcurrentSkipListSet<String> values() {  
  10.         ...  
  11.     }  
  12. }  
class Souper {
    Collection<String> values() {
        ...
    }
}

class ThreadSafeSortedSub extends Souper {
    @Override
    ConcurrentSkipListSet<String> values() {
        ...
    }
}

35 java中可以使用标号进行流程控制

  1. // code goes here  
  2.   
  3. getmeout:{  
  4.     for (int i = 0; i < N; ++i) {  
  5.         for (int j = i; j < N; ++j) {  
  6.             for (int k = j; k < N; ++k) {  
  7.                 //do something here  
  8.                 break getmeout;  
  9.             }  
  10.         }  
  11.     }  
  12. }  
// code goes here

getmeout:{
    for (int i = 0; i < N; ++i) {
        for (int j = i; j < N; ++j) {
            for (int k = j; k < N; ++k) {
                //do something here
                break getmeout;
            }
        }
    }
}

36 初始化块和静态初始化块

  1. public class App {  
  2.     public App(String name) { System.out.println(name + "'s constructor called"); }  
  3.   
  4.     static { System.out.println("static initializer called"); }  
  5.   
  6.     { System.out.println("instance initializer called"); }  
  7.   
  8.     static { System.out.println("static initializer2 called"); }  
  9.   
  10.     { System.out.println("instance initializer2 called"); }  
  11.   
  12.     public static void main( String[] args ) {  
  13.         new App("one");  
  14.         new App("two");  
  15.   }  
  16. }  
public class App {
    public App(String name) { System.out.println(name + "'s constructor called"); }

    static { System.out.println("static initializer called"); }

    { System.out.println("instance initializer called"); }

    static { System.out.println("static initializer2 called"); }

    { System.out.println("instance initializer2 called"); }

    public static void main( String[] args ) {
        new App("one");
        new App("two");
  }
}
打印结果如下:
  1. static initializer called  
  2. static initializer2 called  
  3. instance initializer called  
  4. instance initializer2 called  
  5. one's constructor called  
  6. instance initializer called  
  7. instance initializer2 called  
  8. two's constructor called  
static initializer called
static initializer2 called
instance initializer called
instance initializer2 called
one's constructor called
instance initializer called
instance initializer2 called
two's constructor called

37 在泛型的类型限定中使用&限定接口

  1. public class Baz<T extends Foo & Bar> {}  
public class Baz<T extends Foo & Bar> {}
意为:T是Foo的子类型, 并且实现了Bar接口
  1. public static <A, B extends Collection<A> & Comparable<B>>  
  2. boolean foo(B b1, B b2, A a) {  
  3.    return (b1.compareTo(b2) == 0) || b1.contains(a) || b2.contains(a);  
  4. }  
public static <A, B extends Collection<A> & Comparable<B>>
boolean foo(B b1, B b2, A a) {
   return (b1.compareTo(b2) == 0) || b1.contains(a) || b2.contains(a);
}
在foo方法中, 可以使用Comparable接口中的compareTo方法
 
posted @ 2014-03-26 22:51  dai.sp  阅读(189)  评论(0编辑  收藏  举报