在VM加载接口时调用一些代码

时间:2018-05-18 08:49:30

标签: java android

在普通的Java类中,当VM加载一个类时,它会调用clinit方法,所以我想知道当VM加载一个接口时,它能调用一些代码吗?

例如class B implements Anew B()clinit的VM调用B,VM AA的影响System.out.println("hello")我插入了一些代码,如select *,LAG(Status) OVER(Partition by Name Order by MonthDate,Id) AS PreviousSatus from tab1 order by id

3 个答案:

答案 0 :(得分:0)

在接口中阻塞static {}是不可能的。但是如果您确实需要在加载接口时调用某些代码,则可以使用自定义类加载器来挂接您的接口加载并对其执行某些操作

以下是一个例子:

static class MyClassLoader extends ClassLoader {
        @Override
        public Class<?> loadClass(String name) throws ClassNotFoundException {
            if (name.equals("test.Test1")) {
                ... do whatewer you need on loading class/interface...
            }
            return getParent().loadClass(name);
        }
    }
}

如何在java中正在运行的应用程序中替换类?

还有非常有用的教程:https://zeroturnaround.com/rebellabs/reloading-objects-classes-classloaders/

答案 1 :(得分:0)

如另一个答案中所述,您不能在接口中使用静态部分。但是,您可以使用静态方法和静态最终字段。您可以将两者结合起来进行调试。

interface TestInterface {
    int dummy = init();
    static int init() {
        System.out.println("Loaded TestInterface");
        return 1;
    }
}

答案 2 :(得分:0)

直接不是,Java接口不应包含任何代码,即使您现在可以使用默认方法。以下代码将无法编译:

interface Foo {
    init {
        System.out.println("Loading Foo...");
    }
}

但是,接口可以包含静态字段:

interface Foo {
    static class FooLoader {
        private static Object init() {
            System.out.printf("Initializing %s%n", Foo.class);
        }
    }

    Object NULL = FooLoader.init();
}

同样,它可能会起作用但是

  1. 通过Reflection,它仍然可以调用init()方法,因此可以调用两次
  2. 代码在加载时但是在初始时才真正被调用。要理解,我的意思是检查这个简单的主要内容:

    的System.out.println(&#34; START&#34); 的System.out.println(让Foo.class); 的System.out.println(&#34; END&#34);

  3. 只要您不访问静态成员,Java接口就不会被初始化(参见§5.5 of JVM Specification

    因此,要真正捕获加载时间,您可以使用自定义类加载器或检测API。