Как проверить тип переменной в Java?

120

Как я могу проверить, является ли моя переменная int, array, double и т. Д.?

Изменить: например, как я могу проверить, что переменная является массивом? Есть ли какая-то функция для этого?

клубника
источник
Взгляните на Reflection API .
mschonaker
Очень связанный вопрос с ответами здесь: stackoverflow.com/questions/2674554/… .
А.Алессио

Ответы:

111

Java - это язык со статической типизацией, поэтому компилятор выполняет большую часть этой проверки за вас. После того, как вы объявите переменную определенного типа, компилятор будет гарантировать, что ей когда-либо были присвоены только значения этого типа (или значения, которые являются подтипами этого типа).

Приведенные вами примеры ( int, array, double) - это все примитивы, и у них нет подтипов. Таким образом, если вы объявляете переменную как int:

int x;

Вы можете быть уверены, что он будет только когда-либо int ценности.

Однако, если вы объявили переменную как a List, возможно, что эта переменная будет содержать подтипы List. Примеры из них включают ArrayList:LinkedList и т. Д.

Если у вас есть Listпеременная и вам нужно знать, является ли она переменной ArrayList, вы можете сделать следующее:

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

Однако, если вы поймете, что вам нужно это сделать, вы можете пересмотреть свой подход. В большинстве случаев, если вы следуете объектно-ориентированным принципам, вам не нужно этого делать. Однако из каждого правила, конечно, есть исключения.

pkaeding
источник
3
Оператор instanceof определяет только тип данных объекта, на который указывает переменная. Он не определяет тип данных фактической ПЕРЕМЕННОЙ, как это было изначально запрошено.
GrantRobertson
38

На самом деле довольно легко развернуть собственный тестер, злоупотребляя способностью Java к перегрузке. Хотя мне все еще любопытно, есть ли в sdk официальный метод.

Пример:

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");
    }
}

затем:

Typetester t = new Typetester();
t.printType( yourVariable );
Mvcoile
источник
21
Не лучший метод ИМО. Что произойдет, если я передам какой-нибудь произвольный тип, который не определен в вашем классе Typetester - например, в этом экземпляре String?
Таш Пемхива
6
@TashPemhiwa затем добавьте String и Object к вариантам выбора. Креативность и решение проблем - лучшие активы программиста.
Kato
8
Тем не менее, это может иметь дело только с фиксированным набором предопределенных классов (что противоречит цели объектной ориентации / полиморфизма) и даст вам только что-то вроде «неизвестного класса» для объектов любого другого класса
Algoman
3
Выбор подписи происходит во время компиляции, а не во время выполнения. Таким образом, этот метод не скажет вам ничего, чего вы еще не знали во время компиляции. docs.oracle.com/javase/specs/jls/se7/html/…
jmh
26

a.getClass().getName()- предоставит вам тип данных фактического объекта, на который имеется ссылка a, но не тип данных, для которого переменная aбыла изначально объявлена ​​или для которой впоследствии была приведена.

boolean b = a instanceof String- сообщит вам, является ли фактический объект, на который ссылается, aэкземпляром определенного класса. Опять же, тип данных, который переменнаяa была изначально объявлена ​​как или впоследствии приведенная к преобразованию, не влияет на результат выполнения оператора instanceof.

Я взял эту информацию из: Как узнать тип переменной в java?

Это может случиться. Я пытаюсь разобрать a Stringна int, и я хотел бы знать, Integer.parseInt(s.substring(a, b))выбрасывает ли мой int или мусор, прежде чем я попытаюсь подвести итог.

Кстати, это известно как Отражение. Вот еще немного информации по этому поводу: http://docs.oracle.com/javase/tutorial/reflect/

Глен Пирс
источник
14

Вы можете работать с Integer вместо int, Double вместо double и т.д. (такие классы существуют для всех примитивных типов). Затем вы можете использовать оператор instanceof, напримерif(var instanceof Integer){...}

Алексей Абдугафаров
источник
2
Все, что нам нужно, - это допустимый вариант использования.
Marquis of Lorne,
Звучит как наиболее эффективный подход.
I.Tyger 06
13

Просто используйте:

.getClass().getSimpleName();

Пример:

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

Вывод:

StringBuilder
Debayan
источник
1
Я предлагаю отметить, что это не работает, если randSBсодержит NULL.
Basil
8

Что ж, я думаю, что проверить тип переменной можно таким образом.

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! ");
}

Таким образом, вам не нужно иметь несколько перегруженных методов. Я думаю, что из-за дополнительных преимуществ использовать коллекции вместо массивов - это хорошая практика. Сказав это, я не знаю, как проверить тип массива. Может кто улучшит это решение. Надеюсь это поможет!

PS Да, я знаю, что это тоже не проверяет примитивы.

Amogh
источник
6

Первая часть вашего вопроса бессмысленна. Нет обстоятельств, при которых вы не знаете тип примитивной переменной во время компиляции.

Что касается второй части, единственное обстоятельство, при котором вы еще не знаете, является ли переменная массивом, - это объект. В каком случае object.getClass().isArray()подскажу.

Маркиз Лорн
источник
5
Я мог бы иметь хэш-карту от строки к объекту, поместить int в эту хэш-карту и вытащить ее обратно. Единственное, что я знаю, это то, что это «объект» и, возможно, придется проверить его тип. Не сказать, что это хорошо, а просто сказать, что это возможно.
matty-d
5

Я использовал: if(x.getClass() == MyClass.class){...}

Винисиус Арруда
источник
2

Я не был доволен ни одним из этих ответов, а тот, который был правильным, не имеет объяснений и отрицательных голосов, поэтому я поискал, нашел кое-что и отредактировал его, чтобы его было легко понять. Поиграйте с этим, не так просто, как хотелось бы.

//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);

Вот способ:

public static void checkClass (Object obj) {
    Class cls = obj.getClass();
    System.out.println("The type of the object is: " + cls.getSimpleName());       
}
Нил Риган
источник
1

Ни один из этих ответов не работает, если переменная является неинициализированным универсальным типом.

И из того, что я могу найти, это возможно только с использованием чрезвычайно уродливого обходного пути или путем передачи инициализированного параметра вашей функции, сделав его на месте, см. Здесь:

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

НЕ допустимо, потому что вы не можете Tнапрямую извлечь тип из параметра, так как он стирается во время выполнения.

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

Это работает, потому что вызывающий отвечает за создание экземпляра переменной. out перед вызовом. Это все равно вызовет исключение, если при вызове out имеет значение null, но по сравнению со связанным решением, это, безусловно, самый простой способ сделать это.

Я знаю, что это своего рода конкретное приложение, но поскольку это первый результат в Google для поиска типа переменной с помощью java (и учитывая, что Tэто своего рода переменная), я считаю, что это должно быть включено

iggy12345
источник
0

Вы можете легко проверить это с помощью Java.lang.Class.getSimpleName()метода, только если переменная имеет непримитивный тип. Он не работает с примитивными типами int, long и т. Д.

ссылка - Вот ссылка на документы Oracle

GeekyCoder
источник
0

В основном, например:

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
    }

}
Doktor
источник
1
Небольшая подсказка: когда есть вопрос, которому 10 лет и он имеет> 10 ответов, некоторые из которых имеют> 100 голосов, тогда (не невозможно, но) очень , очень маловероятно, что новый ответ может добавить что-то полезное (в частности, когда это просто фрагмент кода, в котором говорится: «Вот, смотри, это что-то печатает» ...)
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());

}

}

Dev
источник