Jak sprawdzić typ zmiennej w Javie?


Odpowiedzi:


111

Java jest językiem z typami statycznymi, więc kompilator wykonuje większość czynności sprawdzających za Ciebie. Po zadeklarowaniu zmiennej jako określonego typu kompilator zapewni, że będzie ona zawsze przypisywana tylko wartościom tego typu (lub wartościom, które są podtypami tego typu).

Przykłady, które podałeś ( int, tablica, double) te wszystkie są prymitywami i nie ma ich podtypów. Tak więc, jeśli zadeklarujesz zmienną jako int:

int x;

Możesz być pewien, że zawsze będzie zawierał tylko intwartości.

Jeśli jednak zadeklarowałeś zmienną jako a List, możliwe jest, że zmienna będzie zawierała podtypy List. Przykłady te obejmują ArrayList, LinkedListitp

Jeśli miałeś Listzmienną i chciałeś wiedzieć, czy to jest ArrayList, możesz wykonać następujące czynności:

List y;
...
if (y instanceof ArrayList) { 
  ...its and ArrayList...
}

Jeśli jednak uważasz, że musisz to zrobić, możesz przemyśleć swoje podejście. W większości przypadków, jeśli będziesz przestrzegać zasad zorientowanych obiektowo, nie będziesz musiał tego robić. Są oczywiście wyjątki od każdej reguły.


3
Operator instanceof określa tylko typ danych obiektu, do którego odwołuje się zmienna. Nie określa typu danych rzeczywistej VARIABLE, jak pierwotnie zażądano.
GrantRobertson,

38

Właściwie całkiem łatwo jest rzucić własnego testera, nadużywając możliwości przeciążenia metody Java. Chociaż nadal jestem ciekawy, czy w SDK jest jakaś oficjalna metoda.

Przykład:

class Typetester {
    void printType(byte x) {
        System.out.println(x + " is an byte");
    }
    void printType(int x) {
        System.out.println(x + " is an int");
    }
    void printType(float x) {
        System.out.println(x + " is an float");
    }
    void printType(double x) {
        System.out.println(x + " is an double");
    }
    void printType(char x) {
        System.out.println(x + " is an char");
    }
}

następnie:

Typetester t = new Typetester();
t.printType( yourVariable );

21
Nie jest to dobra metoda IMO. Co się stanie, jeśli przekażę dowolny typ, który nie jest zdefiniowany w Twojej klasie Typetester - w tym przypadku na przykład String?
Tash Pemhiwa

6
@TashPemhiwa, a następnie dodaj ciąg i obiekt do wyboru. Kreatywność i rozwiązywanie problemów to największe atuty programistów.
Kato

8
Mimo to może to obsługiwać tylko ustalony zestaw predefiniowanych klas (co jest sprzeczne z celem orientacji obiektowej / polimorfizmu) i daje tylko coś w rodzaju „nieznanej klasy” dla obiektów dowolnej innej klasy
Algoman

3
Wybór podpisu ma miejsce w czasie kompilacji, a nie w czasie wykonywania. Więc ta technika nie powie ci niczego, czego jeszcze nie wiesz w czasie kompilacji. docs.oracle.com/javase/specs/jls/se7/html/ ...
jmh

26

a.getClass().getName()- poda typ danych rzeczywistego obiektu, do którego się odwołuje a, ale nie typ danych, na jaki zmienna azostała pierwotnie zadeklarowana lub na którą została rzutowana.

boolean b = a instanceof String- poda, czy rzeczywisty obiekt, do którego się odwołuje, ajest instancją określonej klasy. Ponownie, typ danych, do którego zmienna azostała pierwotnie zadeklarowana lub na który została następnie rzutowana, nie ma wpływu na wynik operatora instanceof.

Informacje te zaczerpnąłem z: Skąd znasz typ zmiennej w Javie?

To może się zdarzyć. Próbuję przetworzyć a Stringna int i chciałbym wiedzieć, czy mój Integer.parseInt(s.substring(a, b))wyrzuca int lub śmieci, zanim spróbuję to podsumować.

Nawiasem mówiąc, jest to znane jako Odbicie. Oto więcej informacji na ten temat: http://docs.oracle.com/javase/tutorial/reflect/


14

Możesz pracować z Integer zamiast int, Double zamiast double, itd. (Takie klasy istnieją dla wszystkich typów pierwotnych). Następnie możesz użyć operatora instanceof, takiego jakif(var instanceof Integer){...}


2
Wszystko, czego potrzebujemy, to ważny przypadek użycia.
Markiz Lorne

Brzmi jak najbardziej efektywne podejście.
I.Tyger

13

Po prostu użyj:

.getClass().getSimpleName();

Przykład:

StringBuilder randSB = new StringBuilder("just a String");
System.out.println(randSB.getClass().getSimpleName());

Wynik:

StringBuilder

1
Sugeruję zauważyć, że to nie działa, jeśli randSBposiada NULL.
Basil Bourque

8

Cóż, myślę, że sprawdzenie typu zmiennej można zrobić w ten sposób.

public <T extends Object> void checkType(T object) {    
    if (object instanceof Integer)
        System.out.println("Integer ");
    else if(object instanceof Double)
        System.out.println("Double ");
    else if(object instanceof Float)
        System.out.println("Float : ");
    else if(object instanceof List)
        System.out.println("List! ");
    else if(object instanceof Set)
        System.out.println("Set! ");
}

W ten sposób nie musisz mieć wielu przeciążonych metod. Myślę, że dobrą praktyką jest używanie kolekcji zamiast tablic ze względu na dodatkowe korzyści. Powiedziawszy to, nie wiem, jak sprawdzić typ tablicy. Może ktoś mógłby ulepszyć to rozwiązanie. Mam nadzieję że to pomoże!

PS Tak, wiem, że to również nie sprawdza prymitywów.


6

Pierwsza część twojego pytania jest bez znaczenia. Nie ma sytuacji, w której nie znasz typu pierwotnej zmiennej w czasie kompilacji.

Jeśli chodzi o drugą część, jedyną okolicznością, w której nie wiesz, czy zmienna jest tablica, jest to, że jest to obiekt. W takim przypadku object.getClass().isArray()powie.


5
Mógłbym mieć hashmap od ciągu do obiektu, umieścić int w tym hashmap i wyciągnąć go z powrotem. Wiem tylko, że jest to „obiekt” i mogę sprawdzić, jakiego typu jest. Nie mówię, że to dobre, po prostu mówię, że to możliwe.
matty-d


2

Nie byłem zadowolony z żadnej z tych odpowiedzi, a ta, która jest poprawna, nie ma wyjaśnienia ani negatywnych głosów, więc przeszukałem, znalazłem kilka rzeczy i zredagowałem je tak, aby było łatwe do zrozumienia. Baw się tym, nie tak prosto, jak można by się spodziewać.

//move your variable into an Object type
Object obj=whatYouAreChecking;
System.out.println(obj);

// moving the class type into a Class variable
Class cls=obj.getClass();
System.out.println(cls);

// convert that Class Variable to a neat String
String answer = cls.getSimpleName();
System.out.println(answer);

Oto metoda:

public static void checkClass (Object obj) {
    Class cls = obj.getClass();
    System.out.println("The type of the object is: " + cls.getSimpleName());       
}

1

Żadna z tych odpowiedzi nie działa, jeśli zmienna jest niezainicjowanym typem ogólnym

Z tego, co mogę znaleźć, jest to możliwe tylko przy użyciu wyjątkowo brzydkiego obejścia lub przez przekazanie zainicjowanego parametru do funkcji, dzięki czemu jest on na miejscu, patrz tutaj:

<T> T MyMethod(...){ if(T.class == MyClass.class){...}}

NIE jest poprawny, ponieważ nie można bezpośrednio wyciągnąć typu z Tparametru, ponieważ jest on kasowany w czasie wykonywania.

<T> void MyMethod(T out, ...){ if(out.getClass() == MyClass.class){...}}

Działa to, ponieważ obiekt wywołujący jest odpowiedzialny za utworzenie wystąpienia zmiennej outprzed wywołaniem. Spowoduje to zgłoszenie wyjątku, jeśli out ma wartość null po wywołaniu, ale w porównaniu z połączonym rozwiązaniem jest to zdecydowanie najłatwiejszy sposób

Wiem, że jest to rodzaj konkretnej aplikacji, ale ponieważ jest to pierwszy wynik w Google dotyczący znalezienia typu zmiennej w java (i biorąc pod uwagę, że Tjest to rodzaj zmiennej), uważam, że powinien zostać uwzględniony



0

Zasadniczo na przykład:

public class Kerem
{
    public static void main(String[] args)
    {
        short x = 10;
        short y = 3;
        Object o = y;
        System.out.println(o.getClass()); // java.lang.Short
    }

}

1
Mała wskazówka: gdy istnieje pytanie, które ma 10 lat i ma> 10 odpowiedzi, z których niektórzy mają ponad 100 głosów za, to jest (nie jest to niemożliwe, ale) bardzo , bardzo mało prawdopodobne, aby nowa odpowiedź mogła dodać coś pożytecznego (szczególnie, kiedy jest to tylko fragment kodu z napisem „Zobacz, to coś drukuje” ...)
Marco13

-4

public class Demo1 {

Object printType(Object o)
{
    return o;
}
 public static void main(String[] args) {

    Demo1 d=new Demo1();
    Object o1=d.printType('C');
    System.out.println(o1.getClass().getSimpleName());

}

}

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.