【问题标题】:Load Inner Class Java加载内部类 Java
【发布时间】:2011-11-18 00:22:17
【问题描述】:

我在 Java 中有这个类(它来自 JaCoCo 项目):

public class MemoryMultiReportOutput implements IMultiReportOutput {

    private final Map<String, ByteArrayOutputStream> files = new HashMap<String, ByteArrayOutputStream>();

    private final Set<String> open = new HashSet<String>();

    private boolean closed = false;

    public OutputStream createFile(final String path) throws IOException {
        assertFalse("Duplicate output " + path, files.containsKey(path));
        open.add(path);
        final ByteArrayOutputStream out = new ByteArrayOutputStream() {
            @Override
            public void close() throws IOException {
                open.remove(path);
                super.close();
            }
        };
        files.put(path, out);
        return out;
    }

    public void close() throws IOException {
        closed = true;
    }

    public void assertEmpty() {
        assertEquals(Collections.emptySet(), files.keySet());
    }

    public void assertFile(String path) {
        assertNotNull(String.format("Missing file %s. Actual files are %s.",
                path, files.keySet()), files.get(path));
    }

    public void assertSingleFile(String path) {
        assertEquals(Collections.singleton(path), files.keySet());
    }

    public byte[] getFile(String path) {
        assertFile(path);
        return files.get(path).toByteArray();
    }

    public InputStream getFileAsStream(String path) {
        return new ByteArrayInputStream(getFile(path));
    }

    public void assertAllClosed() {
        assertEquals(Collections.emptySet(), open);
        assertTrue(closed);
    }
}

当我编译这个类时,Eclipse 会创建 MemoryMultiReportOutput.classMemoryMultiReportOutput$1.class

第一个问题:Eclipse 为什么要创建MemoryMultiReportOutput$1.class? Eclipse 认为 ByteArrayOutputStream out 是 InnerClass?

但我的问题是,当我加载 MemoryMultiReportOutput.class 时,如何加载父类中存在的所有内部类?

【问题讨论】:

  • 你为什么担心加载内部类?你在写一个类加载器吗?
  • 我有一个调用此类的 JUnit 测试,如果我没有加载 MemoryMultiReportOutput.class 和 MemoryMultiReportOutput$1.class,则 JUnitCore.run(...) 的结果是 ClassNotFound...是的,我有这个ClassLoader...

标签: java eclipse inner-classes


【解决方案1】:

回答你的第一个问题:

final ByteArrayOutputStream out = new ByteArrayOutputStream() {
        @Override
        public void close() throws IOException {
            open.remove(path);
            super.close();
        }
    };

在这里,您正在动态创建 ByteArrayOutputStream 的子类,即匿名。这就是你有另一个 .class 文件的原因。

回答你的第二个问题:

您只能通过超类的实例对象加载对子类可见的父内部类:

Superclass s = new Superclass();
Superclass.Subclass sub = s.new Subclass();

如果内部类是静态的,即顶级嵌套类(因为没有内部静态类这样的东西)可以这样实例化:

Superclass.Subclass s = new Superclass.Subclass();

并且它不需要超类的对象实例。

希望这会有所帮助!

【讨论】:

    【解决方案2】:

    您使用

    创建匿名内部类
    new ByteArrayOutputStream()
    

    这就是您看到MemoryMultiReportOutput$1.class 文件的原因。

    你不需要做任何事情来加载内部类。这会自动发生。

    如果您询问如何从另一个有点不同的类访问内部类。您需要将其标记为 public 或提供将返回该类实例的访问器。你问的是这个吗?

    【讨论】:

    • 要运行 JUnitCore.run(...) 我需要加载 MemoryMultiReportOutput.class 和 MemoryMultiReportOutput$1.class... 我有这个 ClassLoader 来加载类,但它只加载 MemoryMultiReportOutput。类而不是匿名内部类。
    猜你喜欢
    • 2014-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-05
    相关资源
    最近更新 更多