加载内部类Java



我在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是一个内部类?

但我的问题是,当我加载MemoryMultiReportOutput.class我怎么能加载父类存在的所有内部类?

回答第一个问题:

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

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

希望这对你有帮助!

使用

创建一个匿名内部类
new ByteArrayOutputStream()

这就是为什么你看到MemoryMultiReportOutput$1.class文件。

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

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

最新更新