java静态初始化_java-中的静态初始化

java-中的静态初始化

当我试图写这样的东西:

public interface MyInterface {

static {

System.out.println("Hello!");

}

}

编译器无法编译它。

但是当我写这样的东西时:

interface MyInterface {

Integer iconst = Integer.valueOf(1);

}

并将其反编译,我看到了静态初始化:

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

}

您能否向我解释这种行为?

5个解决方案

21 votes

接口不应有副作用,甚至应适用于静态初始化器。 他们将具有高度依赖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() {

}

}

您如何看待何时打印interface Foo initialized? 然后尝试猜测并运行代码。 答案可能会让您感到惊讶。

Holger answered 2020-08-03T00:49:43Z

15 votes

您可以具有静态初始化,但不能具有静态块。 静态初始化需要静态代码块来实现的事实确实改变了Java语法。

关键是您不打算在接口中包含代码(在Java 8之前),但是可以初始化字段。

顺便说一句,您可以有一个嵌套的类或枚举,其中包含所需的代码,您可以在初始化字段时调用它。 ;)

Peter Lawrey answered 2020-08-03T00:49:18Z

6 votes

您可以通过在同一文件中放置第二个非公共类来解决该问题(如果您将其视为问题)。

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";

}

}

使用以下方法进行测试:

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);

}

}

}

印刷品:

Test Hello

Static Hello

Hello again

Hello

Java是一种聪明的语言-它使很难做愚蠢的事情,但并非不可能。 :)

OldCurmudgeon answered 2020-08-03T00:50:16Z

0 votes

接口没有任何初始化块。 遵循以下代码段可能会有所帮助。

public interface MyInterface {

public static final int a;// Compilation error as there is no way for

// explicit initialization

}

public class MyClass {

public static final int a;// Still no error as there is another way to

//initialize variable even though they are final.

static{

a=10;

}

}

Siddappa Walake answered 2020-08-03T00:50:36Z

-1 votes

在接口中声明静态方法永远没有意义。 它们不能通过常规调用MyInterface.staticMethod()执行。 (编辑:由于最后一句话使某些人感到困惑,因此,调用MyClass.staticMethod()会在MyClass上精确执行staticMethod的实现,如果MyClass是接口,则该方法将不存在!)如果通过指定实现类MyImplementor.staticMethod()来调用它们 那么您必须知道实际的类,因此该接口是否包含它是无关紧要的。

更重要的是,静态方法永远不会被覆盖,如果您尝试这样做:

MyInterface var = new MyImplementingClass();

var.staticMethod();

静态规则说必须执行声明的var类型中定义的方法。 由于这是一个接口,因此这是不可能的。

当然,您总是可以从方法中删除static关键字。 一切都会正常。 如果从实例方法中调用它,则可能不得不禁止某些警告。

为了回答下面的一些评论,不能执行“ result = MyInterface.staticMethod()”的原因是它必须执行MyInterface中定义的方法的版本。 但是在MyInterface中无法定义一个版本,因为它是一个接口。 根据定义,它没有代码。

Manish Doshi answered 2020-08-03T00:51:15Z

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值