Skąd znasz typ zmiennej w Javie?

152

Powiedzmy, że deklaruję zmienną:

String a = "test";

I chcę wiedzieć, jaki to jest typ, tj. Wyjście powinno być: java.lang.StringJak to zrobić?

Miguel Ribeiro
źródło
1
Czy naprawdę interesuje Cię typ zmiennej ? A może zależy Ci na rodzaju wartości ? Ponieważ nie można łatwo uzyskać typu zmiennej (w rzeczywistości nie jest to w ogóle możliwe dla zmiennych lokalnych i wymaga refleksji dla pól).
Joachim Sauer
8
@Paul: Uwzględnij Object o = "o";- typ zmiennej to Object, typ wartości to String.
Michael Borgwardt
2
@Paul In List<String> l = new ArrayList<String>();, typ zmiennej to List<String>, typ wartości to ArrayList<String>.
Ben Lings,
1
@Ben Lings Typ zmiennej to java.util.ArrayList, a typ wartości to java.util.ArrayList.
Ajay Takur,
1
@AjayThakur - to różnica między typem czasu kompilacji (statycznym) a typem czasu wykonywania (dynamicznym).
Ben Lings,

Odpowiedzi:

269
a.getClass().getName()
Jaskółka oknówka
źródło
16
To da typ wartości. niekoniecznie typ zmiennej.
Joachim Sauer
7
Po prostu pomyślałem, że tego właśnie szukał OP, ponieważ deklaracja ajest dość oczywista w czasie kompilacji
Martin
4
To zadziałałoby, gdyby typy nie były prymitywami ... Jeśli typ to int, po czym poznać typ?
Miguel Ribeiro
5
@Miguel: ponieważ jedynym sposobem obsługi intwartości jest intzmienna, nie ma możliwości napisania kodu, który obsługuje intwartość i nie zna tego typu. Sprawa jest inna w przypadku, gdy obsługujesz opakowanie Integer, ale wtedy kod tej odpowiedzi znów działa.
Joachim Sauer
1
nie jest to prawdą dla typu pierwotnego.
Mehdi
37

Jeśli chcesz nazwę, użyj metody Martina. Jeśli chcesz wiedzieć, czy jest to instancja określonej klasy:

boolean b = a instanceof String

Martin Konecny
źródło
15
ty też nie jesteś Martinem? :)
seokhoonlee
Drugi Martin ... LOL;)
chankruze
Ten kod Double a = 1d; boolean b = a instanceof String;spowoduje błąderror: incompatible types: Double cannot be converted to String
Alex78191
35

Chciałbym tam rozwinąć odpowiedź Martina ...

Jego rozwiązanie jest raczej przyjemne, ale można je dostosować, aby każdy „typ zmiennej” mógł zostać wydrukowany w ten sposób (w rzeczywistości jest to typ wartości, więcej na ten temat ). To powiedziawszy, „podkręcone” może być mocnym słowem na to. Niezależnie od tego, może być pomocne.

Rozwiązanie Martins:

a.getClass().getName()

Jeśli jednak chcesz, aby działał ze wszystkim, możesz to zrobić:

((Object) myVar).getClass().getName()
//OR
((Object) myInt).getClass().getSimpleName()

W tym przypadku prymityw zostanie po prostu opakowany w Wrapper. W takim przypadku otrzymasz Object of the prymityw.

Sam użyłem tego w ten sposób:

private static String nameOf(Object o) {
    return o.getClass().getSimpleName();
}

Korzystanie z typów generycznych:

public static <T> String nameOf(T o) {
    return o.getClass().getSimpleName();
}
Atspulgs
źródło
Ciekawy. Właśnie wypróbowałem twój kod na: System.out.println (((Object) Integer.parseInt ("12")) .getClass (). GetSimpleName ()); i działa! \ o /
shevy
31

Dowiedziałem się z wyszukiwarki (mój angielski jest bardzo zły, więc kod ...) Jak uzyskać typ zmiennej? UPS :

String str = "test";
String type = str.getClass().getName();
value: type = java.lang.String

Ta metoda :

str.getClass().getSimpleName();
value:String

teraz przykład:

Object o = 1;
o.getClass().getSimpleName();
value:Integer
Kopiuj wklej
źródło
3

Zgadzam się z tym, co powiedział Joachim Sauer, nie można tego wiedzieć (typ zmiennej! Nie typ wartości!), Chyba że twoja zmienna jest atrybutem klasy (i musiałbyś pobrać pola klas, uzyskać odpowiednie pole po nazwie ...)

Właściwie dla mnie jest całkowicie niemożliwe, aby jakakolwiek a.xxx().yyy()metoda udzieliła właściwej odpowiedzi, ponieważ odpowiedź byłaby różna dla dokładnie tego samego obiektu, w zależności od kontekstu, w którym wywołujesz tę metodę ...

Jak powiedział teehoo, jeśli wiesz, jak kompilować zdefiniowaną listę typów do przetestowania, możesz użyć instanceof, ale otrzymasz również podklasy zwracające true ...

Jednym z możliwych rozwiązań byłoby również zainspirowanie się implementacją java.lang.reflect.Fieldi utworzeniem własnej Fieldklasy, a następnie zadeklarowanie wszystkich lokalnych zmiennych jako tej niestandardowej Fieldimplementacji ... ale lepiej znajdź inne rozwiązanie, naprawdę zastanawiam się, dlaczego potrzebujesz zmiennej typ, a nie tylko typ wartości?

Sebastien Lorber
źródło
Ponieważ „ale podklasy również będą zwracać prawdę…” , myślę, że miałeś na myśli „ale klasy nadrzędne również będą zwracać prawdę…” , prawda?
skomisa
3

Użyj funkcji przeciążania operatorów w java

class Test {

    void printType(String x) {
        System.out.print("String");
    }

    void printType(int x) {     
        System.out.print("Int");
    }

    // same goes on with boolean,double,float,object ...

}
epicwhat001
źródło
8
Java nie ma koncepcji przeciążania operatorów, to jest przeciążanie metod
nicoschl
2

Myślę, że mamy tutaj wiele rozwiązań:

  • przykład może być rozwiązaniem.

Czemu? W Javie każda klasa jest dziedziczona z samej klasy Object. Więc jeśli masz zmienną i chciałbyś poznać jej typ. Możesz użyć

  • System.out.println (((Obiekt) f) .getClass (). GetName ());

lub

  • Integer.class.isInstance (1985); // daje prawdę

lub

  • isPrimitive ()

    public static void main(String[] args) {
    
     ClassDemo classOne = new ClassDemo();
     Class classOneClass = classOne();
    
     int i = 5;
     Class iClass = int.class;
    
     // checking for primitive type
     boolean retval1 = classOneClass.isPrimitive();
     System.out.println("classOneClass is primitive type? = " + retval1);
    
     // checking for primitive type?
     boolean retval2 = iClass.isPrimitive();
     System.out.println("iClass is primitive type? = " + retval2);
    }

To da nam:

  1. FAŁSZYWE
  2. PRAWDZIWE

Dowiedz się więcej tutaj: Jak określić typ pierwotny zmiennej pierwotnej?

https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html

http://docs.oracle.com/cd/E26806_01/wlp.1034/e14255/com/bea/p13n/expression/operator/Instanceof.html

Karoly
źródło