2011-11-18 56 views
0

我对Java的这个类(这是从JaCoCo项目):负载内部类的Java

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如何加载父类中的所有内部类?

+0

为什么你担心加载内部类?你在写一个类加载器吗? – Yishai

+0

我有一个调用此类的JUnit测试,如果我没有MemoryMultiReportOutput.class和MemoryMultiReportOutput $ 1.class加载,JUnitCore.run(...)的结果是ClassNotFound ... 是的,我有这[ ClassLoader](http://pastebin.com/TjmLr702)... – josecampos

回答

3

要回答你的第一个问题:

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

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

希望这会有所帮助!

+0

好的,谢谢你... – josecampos

+0

没问题!干杯 – Mechkov

1

您与

new ByteArrayOutputStream() 

这就是为什么你看到MemoryMultiReportOutput$1.class文件创建一个匿名内部类。

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

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

+0

运行JUnitCore.run(...)我需要MemoryMultiReportOutput.class和MemoryMultiReportOutput $ 1.class加载...我有这个[ClassLoader](http://pastebin.com/TjmLr702)来加载类,但它只加载MemoryMultiReportOutput.class而不是匿名内部类。 – josecampos