2011-11-18 7 views
0

J'ai cette classe en Java (il est du projet JaCoCo):charge intérieure de classe 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); 
    } 
} 

Quand je compile cette classe Eclipse et créer MemoryMultiReportOutput.classMemoryMultiReportOutput$1.class.

Première question: Pourquoi Eclipse crée le MemoryMultiReportOutput$1.class? Eclipse considère le ByteArrayOutputStream out une InnerClass?

Mais mon problème est, quand je charge le MemoryMultiReportOutput.class comment puis-je charger toutes les innerclasses présentes dans la classe parente?

+0

Dans quel but vous inquiétez-vous de charger la classe interne? Etes-vous en train d'écrire un chargeur de classe? – Yishai

+0

J'ai un test JUnit qui invoque cette classe et si je n'ai pas chargé MemoryMultiReportOutput.class et MemoryMultiReportOutput $ 1.class, le résultat de JUnitCore.run (...) est ClassNotFound ... Oui, j'ai ceci [ ClassLoader] (http://pastebin.com/TjmLr702) ... – josecampos

Répondre

3

Pour répondre à votre première question:

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

Ici vous créez une sous-classe de la ByteArrayOutputStream à la volée, i.e. anonyme. C'est pourquoi vous avez un autre fichier .class.

Pour répondre à votre deuxième question:

Vous ne pouvez charger les classes internes parents, visibles à la sous-classe, par l'instance d'objet de superclasse:

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

Si la classe interne est statique-à-dire un haut -level classe imbriquée (car il n'y a pas une telle chose que la classe statique intérieure) peut être instancié comme ceci:

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

et il ne nécessite pas une instance d'objet de la superclasse.

Espérons que cela aide!

+0

ok, merci vous ... – josecampos

+0

Pas de problème! Salutations – Mechkov

1

Votre création d'une classe interne anonyme avec le

new ByteArrayOutputStream() 

C'est la raison pour laquelle vous voyez le fichier MemoryMultiReportOutput$1.class.

Vous n'avez rien à faire pour charger les classes internes. Cela arrivera automatiquement.

Si vous demandez comment accéder à la classe interne d'une autre classe un peu différente. Vous devez marquer public ou fournir un accesseur qui renvoie une instance de la classe. Est-ce ce que vous demandiez?

+0

Pour exécuter JUnitCore.run (...) J'ai besoin du MemoryMultiReportOutput.class et du MemoryMultiReportOutput $ 1.class chargé ... J'ai ce [ClassLoader] (http://pastebin.com/TjmLr702) pour charger les classes, mais il charger uniquement la classe MemoryMultiReportOutput.class et non la classe interne anonyme. – josecampos

Questions connexes