- 每个实例拥有一个实例变量;每种类别之下共享一个静态变量。
- 编译器会处理除RuntimeException外的所有Exception。
- try...catch...finally中,finally无论如何都会被最后执行。即使try & catch 内含有return,程序也会在return前先执行finally
- try...catch中,如果有多个同父类(除Exception外)的Exception,catch Exception的顺序从上到下应该是子类->父类。否则父类的Exception处理会掩盖了子类的Exception处理。
- 在一个方法中,如果出现Exception,并处理了该Exception后,没有重新throw该Exception,则try...catch...finally外的代码还会继续被执行。这会对程序产生灾难性影响的。
public static void main(String[] arg) { String key = "yes"; try { midlefun(key); } catch (Exception e) { e.printStackTrace(); } System.out.println("end of main"); } static void midlefun(String key) throws Exception { try { System.out.println("start try"); doRisky(key); System.out.println("end try"); } catch (Exception e) { System.out.println("Exception from midlefun"); // throw new Exception(); //如果注释这一条,"end of midlefun"就会被打印出来 } finally { System.out.println("finally"); } System.out.println("end of midlefun"); } static void doRisky(String key) throws Exception{ System.out.println("start risky"); if("yes".equals(key)) { throw new Exception(); } System.out.println("end risky"); return ; }
- 方法中的Exception应该要自己处理,如果还需要调用者对该异常也做出反应,则需要再throw出来。
-
Java的输入/输出API带有链接类型的串流,它代表来源与目的地之间的连接,连接串流将串流与其他串流连接起来。例如:PipedOutputStream。
一般来讲,串流要两两连接才能做出有意义的事情—其中一个表示连接,另一个则是要被调用方法的。由于Java中有丰富的输入/输出流,只要配合起来就可以完成各种任务,达到最大的实用性!
下面的图是一个演示。保存java的对象到一个文件中。
内部类对外部类有特权,可以自由地存取它的内容,就算是私有的内容也一样。内部类可以把外部的方法或变量当作是自己的。例如:
public class MyOuter {
private int x;
public int getX() {
return x;
}
class MyInner{
void go() {
x = 42; //调用外部类的私有对象
}
}
MyInner inner = new MyInner(); //初始化内部类
public void doStuff() {
inner.go();
}
public static void main(String[] arg) {
MyOuter outer = new MyOuter();
System.out.println(outer.getX());
outer.doStuff();
System.out.println(outer.getX());
}
}
如果需要在外部类中生成内部类变量,则需要首先生成外部类对象。这是由于内部类对外部类的那个特权决定的。
public static void main(String[] arg) {
MyOuter outer = new MyOuter();
System.out.println(outer.getX());
MyOuter.MyInner inner = outer.new MyInner();
inner.go();
System.out.println(outer.getX());
}
内部类一般是在GUI程序中使用比较多。添加ActionListener的时候。
线程(Thread)~线程启动需要有一个Runnable对象。
~线程有三个状态:1.新建(Thread thread = new Thread(runnable););2.可执行(thread.start(););3.执行中(何时被执行由java虚拟机来管理,你无法干预。并且多线程运行中,多个任务会被交替执行,而不是一个一个的被执行);4.堵塞(因为Thread可能在等待其他程序的回复)。
~由于多个Thread由虚拟机来管理交替执行,PS:main函数也是一个Thread,其被执行的顺序都是我们无法预测的。例如下面的代码:
public static void main( String[] args )
{
System.out.println("start");
Thread myThread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("in thread");
}
});
myThread.start();
System.out.println("back to main");
}
并不是每次都能够得到下列输出的:start
back to main
in thread
有可能得到下面的输出:
start
in thread
back to main
这要看虚拟机开心不开心了。^_^
~当某个runnable任务对某个状态敏感,且多个Thread都会操作该状态时,就会产生竞争。这时候可以在操作该状态的方法上,增加修饰符synchronized,以达到加锁的目的。
~无论synchronized关键字加在方法上还是对象上,它取得的锁都是对象,而不是把一段代码或函数当作锁――而且同步方法很可能还会被其他线程的对象访问。
~每个对象只有一个锁(lock)与之相关联。
~实现同步是要很大的系统开销作为代价的,甚至可能造成死锁,所以尽量避免无谓的同步控制。 待续