2010-11-22 3 views
2

Betrachten Sie diesen Code:Ist es möglich, zu erkennen, welche Objekte innerhalb eines anderen Objekts durch Reflektion zur Laufzeit definiert sind?

object A { 
    object AA extends A 
    object AB extends A 
    object AC extends A 
}; class A 

Wie ist es möglich, innerhalb der definierten Objekte zu „sehen“ Objekt A zur Laufzeit? dachte ich eine Methode innerhalb object A mit einigen einfachen Reflexion Code wäre genug, aber es scheint, dass der Compiler die Objekthierarchie bei der Kompilierung abflacht und erstellt die folgenden Klassendateien:

  • A.class - Die Klasse A
  • A$class - Das Begleitobjekt von A
  • A$AA$.class - Das AA Objekt
  • A$AB$.class - Das Objekt AB
  • A$AC$.class - T er AC Objekt

Nach der Kompilierung gibt es keine Anzeichen über AA, AB oder AC im Begleitobjekt A, die meine magicMethod haben würde.

Es scheint, dass die Klasse ClassLoader einige verwandte Methoden zu dem, was ich vorhabe, zu tun, aber alle scheinen den genauen String-Namen der Klasse zu erwarten. Gibt es eine Möglichkeit, den ClassLoader nach allen Klassendateien zu fragen, die mit der Klasse beginnen, von der diese Methode im Pfad dieser Klasse aufgerufen wird (A$)?

+0

gee, du bist ** wirklich ** genau darüber, wie du diese 'MonthDate' Objekte deklarieren willst. –

+0

Ja :-). Im Grunde möchte ich prägnanten DRY-Code, die Möglichkeit, meine eigenen Methoden hinzuzufügen, die Möglichkeit für den Benutzer, ihre eigenen Instanzen ohne einen Typkonflikt mit den deklarierten Instanzen instanziieren und "Selbsterfahrung" benötigen, so dass das Objekt, wie viele Objekte es kennt hält (und kann sie abrufen). Alles ohne spezielle Syntaxen oder Regeln wie das Registrieren der Instanzen zu erfinden. – soc

Antwort

1

Der Codethis.getClass.getDeclaredClassessollte die angeforderten Informationen zurückgeben.

Aber nach ein wenig mit verschiedenen Werkzeugen zu experimentieren, es den Verdacht, dass etwas nicht richtig hier funktioniert.

Ich habe versucht, verschiedene Dinge in Scala mit Klassen innerhalb von Klassen statt Objekten und Java-Quellen und aus dem Verhalten der Beurteilung deutlich die erwarteten Ergebnisse zurückgeben sollte, aber es funktioniert noch nicht.

Entweder ich bin grundsätzlich falsch oder scalac könnte vergessen, einige Bits von Metadaten in die Klassen-Dateien, die es generiert, was zu falschen Informationen über die Reflexion.

Siehe this bug report.

+0

Haben Sie versucht, die Informationen von javap und scalap zu bekommen? Vielleicht kann es etwas helfen. – pedrofurla

+0

Ja. Es sieht wie erwartet aus. Hoffentlich gibt es eine Lösung für dieses Problem. – soc

3

Das zugrunde liegende Problem ist, dass die JVM kein Konzept der inneren Klassen hat. Sie wurden in Java 1.1 hinzugefügt, aber die JVM-Spezifikation blieb zwischen 1.0 und der Einführung von invokedynamic völlig unverändert (ernsthaft!).

Als bisschen wie ein Hack, könnte man immer analysieren die Klassennamen und Split auf $

UPDATE

Um dies zu tun, werden Sie leider die Classpath zu scannen haben.

Eines der bekannteren Anwendungen der Technik ist Apache Commons Entdeckung: http://commons.apache.org/discovery/ (das etwas, das Sie verwenden, könnte Ihr Leben leichter machen)

Frühling auch verwendet den gleichen Ansatz.

+1

Wie finden Sie die Klassennamen, um sie zu analysieren? –

+0

Leider müssen Sie den Klassenpfad scannen. Es scheint heutzutage der letzte Schrei zu sein. –

+1

In diesem Fall würde ein Link oder ein Beispiel für eine kanonische Methode Ihre Antwort erheblich verbessern! –

Verwandte Themen