文章目錄
idea debug快捷鍵
Column 1 | Column 2 |
---|---|
F8 | 單步調試,不進入函數內部 |
F7 | 單步調試,進入函數內部 |
Shift+F7 | 選擇要進入的函數 |
Shift+F8 | 跳出函數 |
Alt+F9 | 運行到斷點 |
Alt+F8 | 執行表達式查看結果 |
F9 | 繼續執行,進入下一個斷點或執行完程序 |
Ctrl+F8 | 設置/取消當前行斷點 |
Ctrl+Shift+F8 | 查看斷點 |
運行時數據區
常量池
棧
final修飾的局部變量(方法內)
大家或多或少都聽過常量是放進常量池中的,但是很容易搞混常量的定義。final修飾的局部變量(方法內)是不是常量呢?答案:不是,可以稱之爲不可變變量(存儲在棧中)
用法
在很多時候我們都可以看到這種用法:
class a {
private produceGoods() {
final Goods goods= new Goods();
addSalt(100, new Completion() {
@Override
public void successed() {
System.out.println(goods.name + "add salt success!");
}
});
}
private addSalt(int degree, Completion completion) {
new Thread(()-> {
completion.successed();
}).start();
}
}
疑惑:
內部類和外部類是處於同一個級別的,內部類不會因爲定義在方法中就會隨着方法的執行完畢就被銷燬。當外部類的方法結束時,goods局部變量就會被銷燬了,但是內部類對象可能還存在(只有沒有人再引用它時,纔會死亡)。這裏就出現了一個矛盾:內部類對象訪問了一個不存在的變量。而用final修飾後,可以解決。 final修飾過的局部變量產生了什麼變化呢?
解釋:
局部變量複製了一份作爲內部類的成員變量,這樣當局部變量死亡後,內部類仍可以訪問它,實際訪問的是局部變量的"copy"。這樣就好像延長了局部變量的生命週期。將局部變量複製爲內部類的成員變量時,必須保證這兩個變量是一樣的,也就是如果我們在內部類中修改了成員變量,方法中的局部變量也得跟着改變,怎麼解決問題呢?
就將局部變量設置爲final,對它初始化後,我就不讓你再去修改這個變量,就保證了內部類的成員變量和方法的局部變量的一致性。這實際上也是一種妥協。
多線程
Excutor框架
異步執行框架,將任務的提交和執行分離開
ThreadPoolExecutor
JAVA8
函數式編程
函數式接口
含義
1、是一個接口
2、該接口由@FunctionalInterface裝飾
3、該接口中只能有一個抽象方法,故又稱爲SAM(Single Abstract Method interface)
作用
主要用於Lambda表達式和方法引用
示例
如下是consumer接口:
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
}
那我們就可以使用Lambda表達式來表示該接口的一個實現(注:JAVA 8 之前一般是用匿名類實現的):
Consumer<String> servive = msg -> {System.out.println(msg);};
msg.accept("Hello world");
輸出:Hello world
解釋:
1、Lambda表達式表示{}的實現的就是consumer的accept()方法,當你調用accept()的時候就會輸出msg的內容
comsumer接口
含義
對入參進行一系列處理,沒有返回值,就是消費者,入參的傳入是調用accept()方法;因爲是函數式接口,可以用lambda表達式來實現