Ser*_*zov 44 java interface static-initialization
当我试着写这样的东西时:
public interface MyInterface {
static {
System.out.println("Hello!");
}
}
Run Code Online (Sandbox Code Playgroud)
编译器无法编译它.
但是当我写这样的东西时:
interface MyInterface {
Integer iconst = Integer.valueOf(1);
}
Run Code Online (Sandbox Code Playgroud)
并反编译它,我看到静态初始化:
public interface MyInterface{
public static final java.lang.Integer i;
static {};
Code:
0: iconst_1
1: invokestatic #1; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
4: putstatic #2; //Field i:Ljava/lang/Integer;
7: return
}
Run Code Online (Sandbox Code Playgroud)
你能告诉我这个行为吗?
Hol*_*ger 21
接口不应该有副作用,甚至应用于静态初始化器.它们将具有高度JVM实现依赖性行为.请查看以下代码
public class InterfaceSideEffects {
public static void main(String[] args) {
System.out.println("InterfaceSideEffects.main()");
Impl i=new Impl();
System.out.println("Impl initialized");
i.bla();
System.out.println("Impl instance method invoked");
Foo f=new Impl();
System.out.println("Impl initialized and assigned to Foo");
f.bla();
System.out.println("Foo interface method invoked");
}
}
interface Foo {
int dummy=Bar.haveSideEffect();
void bla();
}
class Bar {
static int haveSideEffect() {
System.out.println("interface Foo initialized");
return 0;
}
}
class Impl implements Foo {
public void bla() {
}
}
Run Code Online (Sandbox Code Playgroud)
你觉得什么时候interface Foo initialized
打印?之后尝试猜测并运行代码.答案可能会让你大吃一惊.
Pet*_*rey 16
您可以进行静态初始化,但不能使用静态块.静态初始化需要实现静态代码块的事实确实会改变Java语法.
关键是你不打算在接口中使用代码(在Java 8之前),但是你可以初始化字段.
顺便说一句,你可以有一个嵌套的类或枚举,它有你想要的代码,你可以在初始化字段时调用它.;)
您可以通过在同一个文件中放置第二个非公共类来解决问题 - 如果您将其视为问题.
public interface ITest {
public static final String hello = Hello.hello();
}
// You can have non-public classes in the same file.
class Hello {
static {
System.out.println("Static Hello");
}
public static String hello() {
System.out.println("Hello again");
return "Hello";
}
}
Run Code Online (Sandbox Code Playgroud)
用以下方法测试:
public class Test {
public void test() {
System.out.println("Test Hello");
System.out.println(ITest.hello);
}
public static void main(String args[]) {
try {
new Test().test();
} catch (Throwable t) {
t.printStackTrace(System.err);
}
}
}
Run Code Online (Sandbox Code Playgroud)
打印:
Test Hello
Static Hello
Hello again
Hello
Run Code Online (Sandbox Code Playgroud)
Java是一种如此聪明的语言 - 它使得很难做出愚蠢的事情,但并非不可能.:)
归档时间: |
|
查看次数: |
18830 次 |
最近记录: |