簡體   English   中英

為什么在Java接口中的static final變量可以被本地var覆蓋?

[英]why in java static final variable in interface can be overridden by a local var?

我知道靜態意味着,內存中只有一個實例。 我知道final表示它不能更改或子類化,我也知道java接口中定義的任何變量都是static final

所以現在這是一個問題,為什么我可以在“ XFace”類的“ MyFace”接口中重載最終的靜態變量“ a”?

例:

public interface MyFace {
    static final int a = 15;

    void smile();
}

然后在這堂課中,我可以很容易地乘搭當地的a

public class XFace implements MyFace {

    @Override
    public void smile() {
        int a=3;  // over riding interface's a variable and suprsingly it works !
        System.out.println(a*2);  // will print 6
    }

為什么我可以在smile()方法中定義int a = 3? 是不是最終的和靜態的? 怎么可以覆蓋它?

它不會被覆蓋,而是被陰影覆蓋,這意味着有一個更接近的變量具有相同的簡單名稱優先。 您仍然可以通過使用static final MyFace.a較長名稱MyFace.a來使用它。

只需看一下兩種不同用法的字節碼(使用局部變量a和不使用局部變量a)。 您可能會看到,如果僅定義了static a,則編譯器將直接使用30 (3: bipush 30)如果定義了局部變量a,則將局部變量1 local1壓入,那么將完成乘法運算。

   5:   iload_1
       6:   iconst_2
       7:   imul

如果要同時使用它們,則必須在定義靜態變量的地方使用用法類名稱。

System.out.println(a*2);  // will print 6
System.out.println(MyFace.a); //will print 15

這是定義示例代碼局部變量a的示例

public class XFace implements MyFace {

    @Override
    public void smile() {
        int a=3; 
        System.out.println(a*2);  // will print 6

    }
}

Compiled from "XFace.java"
public class XFace extends java.lang.Object implements MyFace{
public XFace();
  Code:
   0:   aload_0
   1:   invokespecial   #10; //Method java/lang/Object."<init>":()V
   4:   return

public void smile();
  Code:
   0:   iconst_3
   1:   istore_1
   2:   getstatic       #17; //Field java/lang/System.out:Ljava/io/PrintStream;
   5:   iload_1
   6:   iconst_2
   7:   imul
   8:   invokevirtual   #23; //Method java/io/PrintStream.println:(I)V
   11:  return


}


*********************************************

這是示例代碼靜態變量a的定義

public class XFace implements MyFace {

    @Override
    public void smile() {
        //int a=3; 
        System.out.println(a*2);  // will print 30

    }
}

Compiled from "XFace.java"
public class XFace extends java.lang.Object implements MyFace{
public XFace();
  Code:
   0:   aload_0
   1:   invokespecial   #10; //Method java/lang/Object."<init>":()V
   4:   return

public void smile();
  Code:
   0:   getstatic       #17; //Field java/lang/System.out:Ljava/io/PrintStream;
   3:   bipush  30
   5:   invokevirtual   #23; //Method java/io/PrintStream.println:(I)V
   8:   return

}

從編譯的類文件中打印字節碼,請使用$ JDK_HOME / bin下的javap工具

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM