java為什麼匿名內部類的引數引用時final?

時間 2021-06-01 04:12:46

1樓:椒圖

public class InnerClass {

private int counts = 10;

public void test() {

new Thread(new Runnable() {

private String a(){

counts++;

System.out.println("in a..." + counts);

return Integer.toString(counts);

Override

public void run() {

String s = a();

counts = Integer.parseInt(s);

System.out.println("in run, " + counts);

start();

public int getCounts() {

return this.counts;

public static void main(String args) {

InnerClass innerClass = new InnerClass();

innerClass.test();

try {

Thread.sleep(1000);

catch (InterruptedException e) {

e.printStackTrace();

System.out.println( "in main, " + innerClass.getCounts());

上面這個類例項變數counts沒有用final,而且是傳值,但在匿名內部類new Runnable() 裡可以修改外部類的例項變數.如果copy-by-value 或者是 jdk8 悄悄加了個final ,都不應該能修改counts的值才對,但事實上可以修改.內部匿名類可以修改外部類的例項變數.

2樓:付亮亮

反編譯一下生成的class就知道了,匿名類編譯的時候生成了相應的字段來capture訪問的區域性變數,為了和區域性變數保持一致性,內部類不能修改這個變數,所以需要final。

3樓:周鵬

事實上,除了匿名內部類內部,方法和作用域內的內部類內部使用的外部變數也必須是 final 的。原因如下:

內部類會自動拷貝外部變數的引用,為了避免:1. 外部方法修改引用,而導致內部類得到的引用值不一致 2.

內部類修改引用,而導致外部方法的引數值在修改前和修改後不一致。於是就用 final 來讓該引用不可改變。

至於這是基於語法上的考慮還是由於實現機制上的限制,我就沒有繼續考究了。

為什麼內部類的private變數可被外部類直接訪問?

夏蟲 成員內部類首先是外部類的成員 key 所以可以互相訪問對方的靜態變數和靜態方法 和修飾符無關,修飾符是對其他類而言,對外部類無效 非靜態內部類不能有靜態的東西 外部類訪問內部類非靜態的東西需要建立內部類物件,所以非靜態內部類一定要例項化才能訪問 非靜態內部類必須依賴外部類物件,所以也可以訪問外...

java中為什麼建構函式中的引數傳遞乙個類的物件來實現直接在該類中生成乙個想要傳遞類的物件?

烏索普 兩種不同用法,畢竟是函式引數,你不但可以傳本類物件,也可以傳子類物件,不需要改什麼東西。如果在類裡面寫死,那麼你再想修改。就只能去類裡面改了 酷安小黃 題主,你是怎麼在類B建立乙個A的引用,然後在測試類中構建B類的物件的?傳引數只能按照你注釋之後的那樣穿,類與類之間才能關聯起來。並不是哪種好...

java中帶引數的try 語法含義是什麼?

斯巴拉西 挺好用的語法,不用寫一大堆finally來關閉資源,所有實現Closeable的類宣告都可以寫在裡面,最常見於流操作,socket操作,新版的httpclient也可以 需要注意的是,try 的括號中可以寫多行宣告,每個宣告的變數型別都必須是Closeable的子類,用分號隔開.樓上說不能...