加载内部类Java

时间:2011-11-18 00:22:17

标签: java eclipse inner-classes

我有这个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时如何加载父类中存在的所有内部类?

2 个答案:

答案 0 :(得分:3)

回答你的第一个问题:

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

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

回答你的第二个问题:

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

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

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

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

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

希望这有帮助!

答案 1 :(得分:1)

使用

创建匿名内部类
new ByteArrayOutputStream()

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

您无需执行任何操作来加载内部类。这将自动发生。

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