为什么在java中,接口中的静态最终变量可以被本地var覆盖?

时间:2013-11-24 10:23:27

标签: java interface static final

我知道静态意味着,内存中只有一个实例。 我知道final意味着它无法更改或子类化,我也知道在java接口中定义的任何变量都是静态最终的

所以现在问题是,为什么我可以在“XFace”类的界面“MyFace”中超越最终的静态变量“a”?

示例:

public interface MyFace {
    static final int a = 15;

    void smile();
}

然后在课堂上,我可以轻松地驾驶a,用本地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?是不是“一个”最终和静态?怎么可能被覆盖?

2 个答案:

答案 0 :(得分:12)

它没有被覆盖,它是阴影,这意味着有一个更接近的变量,它具有优先级相同的简单名称。您仍然可以使用static final更长的名称来使用MyFace.a

答案 1 :(得分:0)

只看两个不同用法的字节码(使用局部变量a而不使用它)。您可能会看到,如果只定义了静态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工具