2011-11-18 43 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