Wszystko, co próbuję zrobić, to uzyskać aktualną nazwę klasy, a java dołącza bezużyteczny nonsens 1 $ na końcu nazwy mojej klasy. Jak mogę się go pozbyć i zwrócić tylko prawdziwą nazwę klasy?
Gdzie dzwonisz? Czy pochodzi z anonimowej klasy wewnętrznej? Czy możesz dodać więcej kodu, który pokazuje szczegóły dotyczące definicji klasy i skąd ta linia jest wywoływana?
plainjimbo
8
Więc wszystko, czego chcesz, toString className = getClass().getName().substring(0, getClass().getName().indexOf("$"))
josh.trow
9
Jeśli tak $1, bo nazwa klasy to $1. Jeśli oczekujesz czegoś innego, użyj thisodpowiedniej klasy zamiast niewłaściwej.
ceving
Odpowiedzi:
247
„1 $” nie jest „bezużytecznym nonsensem”. Jeśli twoja klasa jest anonimowa, dodawana jest liczba.
Jeśli nie chcesz samej klasy, ale jej klasy deklarującej, możesz użyć getEnclosingClass(). Na przykład:
Pamiętaj jednak, że nie jest to obecna nazwa klasy. Klasa anonimowa jest inną klasą niż klasa zamykająca. Sprawa jest podobna w przypadku klas wewnętrznych.
Ale co jeśli klasa zamykająca jest również anonimową klasą wewnętrzną? Czy nie musisz rekurencyjnie uzyskiwać klasę zamykającą, dopóki ona nie zwróci null, i użyć ostatniej nieklasy, nullktórą dostałeś?
W rzeczywistości nie, to nie zadziała. To pytanie wskazuje, że ma anonimową klasę wewnętrzną i w tym przypadku zwraca getSimpleName ()""
vikingsteve
48
Chociaż to nie odpowiada na pytanie, ten post SO jest obecnie w najlepszych wynikach dla „get class name java” w google, więc nadal jest pomocny dla społeczności.
EdgeCaseBerg,
6
Zwróci nazwę bez przestrzeni nazw pakietów. Dobry!
Oleg Abrazhaev
31
Spróbuj użyć tego
this.getClass().getCanonicalName()lub this.getClass().getSimpleName(). Jeśli jest to anonimowa klasa, użyjthis.getClass().getSuperclass().getName()
Właściwie to robi. W zależności Jeśli próbujesz uzyskać nazwę klasy abstrakcyjnej, którą wdrażasz za pomocą klasy anonimowej, właśnie tego używasz.
MirroredFate
w jego przypadku (klasa anonimowa) prosta nazwa jest pusta, nazwa kanoniczna jest pusta, a nadklasa to Object.
Bozho
Tak, tak, nie. Moje pierwsze dwa to tylko domysły, trzeci jednak jest poprawny. Anonimowa klasa jest podklasą klasy, którą implementuje. Właśnie dlatego działają. Tak więc nadklasa jest klasą abstrakcyjną.
MirroredFate
Dziwne, czy nie jest to super klasa, z której dziedziczysz? Handler nie dziedziczy po mojej klasie, jest tylko członkiem
aryaxt
Umm ... Przetestowałem to i okazało się, że nadklasą klasy anonimowej jest klasa abstrakcyjna. Ponownie sprawdzę moją logikę ... ale kiedy otrzymuję wynik, który ma sens, nie sądzę, że to ja popełniłem błąd ....
MirroredFate
10
Możesz użyć this.getClass().getSimpleName()tak:
import java.lang.reflect.Field;publicclassTest{int x;int y;publicvoid getClassName(){String className =this.getClass().getSimpleName();System.out.println("Name:"+ className);}publicvoid getAttributes(){Field[] attributes =this.getClass().getDeclaredFields();for(int i =0; i < attributes.length; i++){System.out.println("Declared Fields"+ attributes[i]);}}publicstaticvoid main(String args[]){Test t =newTest();
t.getClassName();
t.getAttributes();}}
ta odpowiedź jest spóźniona, ale myślę, że można to zrobić w kontekście anonimowej klasy programu obsługi.
powiedzmy:
class A {void foo(){
obj.addHandler(newHandler(){void bar(){String className=A.this.getClass().getName();// ...}});}}
osiągnie ten sam wynik. dodatkowo jest to całkiem wygodne, ponieważ każda klasa jest definiowana w czasie kompilacji, więc żadna dynamika nie jest uszkodzona.
powyżej, jeśli klasa jest naprawdę zagnieżdżona, tzn. Afaktycznie jest ujęta przez B, klasę B można łatwo określić jako:
W twoim przykładzie thisprawdopodobnie odnosi się do anonimowej instancji klasy. Java nadaje nazwę tym klasom, dodając $numberdo nazwy klasy zamykającej.
Nieanonimowe klasy wewnętrzne są nazywane Zewnętrzne $ Wewnętrzne. To będzie anonimowa klasa.
Duncan McGregor
1
Zakładam, że dzieje się tak w przypadku anonimowej klasy. Kiedy tworzysz anonimową klasę, faktycznie tworzysz klasę, która rozszerza klasę, której imię masz.
„Czystszym” sposobem na uzyskanie pożądanej nazwy jest:
Jeśli twoja klasa jest anonimową klasą wewnętrzną, getSuperClass()powinna dać ci klasę, z której została utworzona. Jeśli utworzyłeś go z interfejsu, jesteś w pewnym sensie SOL, ponieważ najlepsze, co możesz zrobić, togetInterfaces() może dać ci więcej niż jeden interfejs.
„Hacky” polega na tym, aby po prostu uzyskać nazwę getClassName()i użyć wyrażenia regularnego, aby upuścić $1.
Nie dodaje to niczego, czego żadna inna odpowiedź jeszcze nie powiedziała. Cała kwestia pętli / tablicy nie ma znaczenia. Powinieneś również przyjrzeć się, jak formatowanie kodu działa na pytania / odpowiedzi.
Istnieje kilka interfejsów API refleksji, które zwracają klasy, ale dostęp do nich można uzyskać tylko wtedy, gdy klasa została już uzyskana bezpośrednio lub pośrednio.
Class.getSuperclass()Returns the superclassfor the given class.Class c = javax.swing.JButton.class.getSuperclass();Thesuperclass of javax.swing.JButton is javax.swing.AbstractButton.Class.getClasses()
Zwraca wszystkie klasy publiczne, interfejsy i wyliczenia, które są członkami klasy, w tym elementy odziedziczone.
Class<?>[] c =Character.class.getClasses();
Znak zawiera dwie klasy składowe Character.Subset i
Character.UnicodeBlock.
Class.getDeclaredClasses()Returns all of the classes interfaces, and enums that are explicitly declared in thisclass.Class<?>[] c =Character.class.getDeclaredClasses();Character contains two public member classes Character.Subset and Character.UnicodeBlock and one privateclass
Character.CharacterCache.
Class.getDeclaringClass()
java.lang.reflect.Field.getDeclaringClass()
java.lang.reflect.Method.getDeclaringClass()
java.lang.reflect.Constructor.getDeclaringClass()Returns the Class in which these members were declared.AnonymousClassDeclarations will not have a declaring class but will
mieć klasę zamykającą.
import java.lang.reflect.Field;Field f =System.class.getField("out");Class c = f.getDeclaringClass();The field out is declared in System.publicclassMyClass{staticObject o =newObject(){publicvoid m(){}};staticClass<c>= o.getClass().getEnclosingClass();}The declaring class of the anonymous class defined by o is null.Class.getEnclosingClass()Returns the immediately enclosing class of the class.Class c =Thread.State.class().getEnclosingClass();The enclosing class of the enumThread.State is Thread.publicclassMyClass{staticObject o =newObject(){publicvoid m(){}};staticClass<c>= o.getClass().getEnclosingClass();}The anonymous class defined by o is enclosed by MyClass.
String className = getClass().getName().substring(0, getClass().getName().indexOf("$"))
$1
, bo nazwa klasy to$1
. Jeśli oczekujesz czegoś innego, użyjthis
odpowiedniej klasy zamiast niewłaściwej.Odpowiedzi:
„1 $” nie jest „bezużytecznym nonsensem”. Jeśli twoja klasa jest anonimowa, dodawana jest liczba.
Jeśli nie chcesz samej klasy, ale jej klasy deklarującej, możesz użyć
getEnclosingClass()
. Na przykład:Możesz przenieść to w jakiś statyczny sposób.
Pamiętaj jednak, że nie jest to obecna nazwa klasy. Klasa anonimowa jest inną klasą niż klasa zamykająca. Sprawa jest podobna w przypadku klas wewnętrznych.
źródło
null
, i użyć ostatniej nieklasy,null
którą dostałeś?Próbować,
Będzie to działać, dopóki nie użyjesz go w metodzie statycznej.
źródło
""
Spróbuj użyć tego
this.getClass().getCanonicalName()
lubthis.getClass().getSimpleName()
. Jeśli jest to anonimowa klasa, użyjthis.getClass().getSuperclass().getName()
źródło
Możesz użyć
this.getClass().getSimpleName()
tak:źródło
Połączenie obu odpowiedzi. Drukuje również nazwę metody:
źródło
ta odpowiedź jest spóźniona, ale myślę, że można to zrobić w kontekście anonimowej klasy programu obsługi.
powiedzmy:
osiągnie ten sam wynik. dodatkowo jest to całkiem wygodne, ponieważ każda klasa jest definiowana w czasie kompilacji, więc żadna dynamika nie jest uszkodzona.
powyżej, jeśli klasa jest naprawdę zagnieżdżona, tzn.
A
faktycznie jest ujęta przezB
, klasę B można łatwo określić jako:źródło
W twoim przykładzie
this
prawdopodobnie odnosi się do anonimowej instancji klasy. Java nadaje nazwę tym klasom, dodając$number
do nazwy klasy zamykającej.źródło
Zakładam, że dzieje się tak w przypadku anonimowej klasy. Kiedy tworzysz anonimową klasę, faktycznie tworzysz klasę, która rozszerza klasę, której imię masz.
„Czystszym” sposobem na uzyskanie pożądanej nazwy jest:
Jeśli twoja klasa jest anonimową klasą wewnętrzną,
getSuperClass()
powinna dać ci klasę, z której została utworzona. Jeśli utworzyłeś go z interfejsu, jesteś w pewnym sensie SOL, ponieważ najlepsze, co możesz zrobić, togetInterfaces()
może dać ci więcej niż jeden interfejs.„Hacky” polega na tym, aby po prostu uzyskać nazwę
getClassName()
i użyć wyrażenia regularnego, aby upuścić$1
.źródło
Oto wariant Androida, ale tę samą zasadę można zastosować również w zwykłej Javie.
źródło
Przekonałem się, że działa to w moim kodzie, jednak mój kod usuwa klasę z tablicy w pętli for.
źródło
Interfejsy API refleksji
źródło