2016-04-20 13 views
7

Biorąc pod uwagę pełną nazwę klasy, którą można załadować za pomocą Class.forName(), czy istnieje sposób na przekształcenie nazwy w wynik ładowania klasy i wywołanie metody getSimpleName() bez rzeczywistej próby załadowania klasa? Potrzebuję tej zdolności do celów refleksji.Jaki jest najlepszy sposób na przybliżenie class.getSimpleName() bez ładowania klasy?

+1

Domyślam się, że musiałbyś zaimplementować logikę samodzielnie - jest to głównie pobieranie ostatniego elementu w '.' oddzielonym' String'; z pewnymi dzwonkami i gwizdami ... –

+0

@BoristheSpider i ciąg może również zawierać '$' – wero

+0

@wero yup, "dzwony i gwizdki" - jeśli to '\ $ \ d + $', to 'null', inaczej podzielone na' $ '. –

Odpowiedz

4

Zamierzam powiedzieć, że nie można tego zrobić po prostu na podstawie nazwy.

Można spróbować podzielić na . i $, ale kod ten przykład pokazuje, że nie zawsze jest oczywiste, gdzie prosta nazwa zaczyna:

class Ideone 
{ 
    private static class Bar {}; 

    public static void main (String[] args) throws java.lang.Exception 
    { 
     class Foo$o { 
     class Bar$bar {} 
     }; 
     class Foo$o$Bar { 
     class Bar$bar {} 
     }; 
     class Foo$o$Bar$Bar$bar {} 
     print(Ideone.class); 
     print(Bar.class); 
     print(Foo$o.class); 
     print(Foo$o.Bar$bar.class); 
     print(Foo$o$Bar.Bar$bar.class); 
     print(Foo$o$Bar$Bar$bar.class); 
    } 

    private static void print(Class<?> clazz) { 
     System.out.printf("fqn=%s, sn=%s%n", clazz.getName(), clazz.getSimpleName()); 
    } 
} 

wyjściowa:

fqn=Ideone, sn=Ideone 
fqn=Ideone$Bar, sn=Bar 
fqn=Ideone$1Foo$o, sn=Foo$o 
fqn=Ideone$1Foo$o$Bar$bar, sn=Bar$bar 
fqn=Ideone$1Foo$o$Bar$Bar$bar, sn=Bar$bar 
fqn=Ideone$2Foo$o$Bar$Bar$bar, sn=Foo$o$Bar$Bar$bar 

Ideone demo

tzn. Jeśli miałbyś powiedzieć "trochę imienia po ostatnim $ lub . ", mylisz się.

Jedynym rozstrzygający sposób, aby to zrobić, to załadować klasę, potencjalnie bez inicjalizacji:

Class<?> clazz = Class.forName(className, false, someClassLoadeR); 
+0

Albo wymyślić obszerny zestaw przypadków - jak wykazałeś, nie ma ich wiele - i wdrożyć go. Testowanie jednostkowe byłoby dość banalne. –

+1

@BoristheSpider, ale możesz mieć zagnieżdżoną klasę o nazwie 'Fo' z klasą zagnieżdżoną o nazwie' o'. –

+0

O tak, widzę - w lokalnej nazwie klasy znajduje się '1'. –

0

Jak wykazały odpowiedzią @AndyTurner nie można wyprowadzić prostą nazwę od wykwalifikowanego klasy String we wszystkich przypadki.

Ale jeśli ograniczenie bez faktycznie próbuje załadować klasę nie zabraniają, aby odczytać zawartość pliku klasy, można wykonać następujące czynności (dla przypadków brzegowych):

  1. Get InputStream dla zawartości pliku klasy poprzez Class.getResourceAsStream()
  2. Parsuj początek pliku klasy i przeczytaj nazwę super klasy z puli stałej.
  3. (zgodnie z komentarzem @shmosel) Implementacja logiki Class.getSimpleName(). Nazwa super klasy umożliwia zastąpienie Class.getSimpleBinaryString() bazującej na już załadowanej klasie.
+1

To uczucie jolly ciężko, a nie tylko ładowanie klasy. –

+0

@AndyTurner PO będzie wiedział, czy to warte wysiłku. – wero

Powiązane problemy