[读书笔记] Think in Java r_8

2017-06-01  本文已影响0人  十旋转45度

P108 finalize()

The odd thing about this is that you call gc( ) before you call runFinalization( ), which seems to contradict the JavaSoft documentation which claims that finalizersare run first, and then the storage is released. However, if you call runFinalization( ) first, and then gc( ), the finalizers will not be executed.

P131 protected

同一个包内的所有类可以访问,异包的子类也可以访问

P183 static inner class

To understand the meaning of static when applied to inner classes, you must keep in mind the idea that the object of the inner class implicitly keeps a handle to the object of the enclosing class that created it. When you say an inner class is static, this is not true, which means:

  1. You don’t need an outer-class object in order to create an object of a static inner class.
  2. You can’t access an outer-class object from an object of a static inner class.

P183 inheriting from inner classes

Because the inner class constructor must attach to a handle of the enclosing class object, things are slightly complicated when you inherit from an inner class. The problem is that the “secret” handle to the enclosing class object must be initialized, and yet in the derived class there’s no longer a default
object to attach to. The answer is to use a syntax provided to make the association explicit:

//: InheritInner.java
// Inheriting an inner class
class WithInner {
class Inner {}
}
public class InheritInner
extends WithInner.Inner {
//! InheritInner() {} // Won't compile
InheritInner(WithInner wi) {
wi.super();
}
public static void main(String args[]) {
WithInner wi = new WithInner();
InheritInner ii = new InheritInner(wi);
}
} ///:~

You can see that InheritInner is only extending the inner class, not the outer one. But when it comes time to create a constructor, the default one is no good and you can’t just pass a handle to an enclosing object. In addition, you must use the syntax

enclosingClassHandle.super();

inside the constructor. This provides the necessary handle and the program will then compile.

P240 try,finally,Exception

//: LostMessage.java
// How an exception can be lost
class VeryImportantException extends Exception {
    public String toString() {
        return "A very important exception!";
    }
}
class HoHumException extends Exception {
    public String toString() {
        return "A trivial exception";
    }
}
public class LostMessage {
    void f() throws VeryImportantException {
        throw new VeryImportantException();
    }
    void dispose() throws HoHumException {
        throw new HoHumException();
    }
public static void main(String args[]) throws Exception {
    LostMessage lm = new LostMessage();
    try {
        lm.f();
     } finally {
        lm.dispose();
     }
    }
} ///:~

The output is:

A trivial exception
at LostMessage.dispose(LostMessage.java:21)
at LostMessage.main(LostMessage.java:29)

You can see that there’s no evidence of the VeryImportantException, which is simply replaced by the
HoHumException in the finally clause. This is a rather serious pitfall, since it means an exception can be completely lost, and in a far more subtle and difficult-to-detect fashion than the example above. In contrast, C++ treats the situation where a second exception is thrown before the first one is handled as a dire programming error. Perhaps a future version of Java will repair the problem (the above results were produced with Java 1.1).

P243 Exception Caught order

When an exception is thrown, the exception-handling system looks through the “nearest” handlers in
the order they are written.
If you try to “mask” the derived-class exceptions by putting the base-class catch clause first, like this:

try {
    throw new Sneeze();
} catch(Annoyance e) {
    System.out.println("Caught Annoyance");
} catch(Sneeze d) {
    System.out.println("Caught Sneeze");
}

The compiler will give you an error message, since it sees that the Sneeze catch-clause can never be reached.

上一篇下一篇

猜你喜欢

热点阅读