Як перевірити тип змінної в Java?


120

Як я можу перевірити, щоб переконатися, що моя змінна - це int, масив, double та інше ...?

Редагувати: Наприклад, як я можу перевірити, чи є змінною масив? Чи є якась функція для цього?


Погляньте на API Reflection .
mschonaker

Дуже пов'язане питання з відповідями тут: stackoverflow.com/questions/2674554 / ... .
A.Alessio

Відповіді:


111

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

Наведені вами приклади ( int, масив double) - це все примітиви, і їх немає підтипів. Таким чином, якщо ви визначите змінну такою, як int:

int x;

Ви можете бути впевнені, що це буде лише колись intзначення.

Якщо ви оголосили змінну як a List, можливо, змінна буде містити підтипи List. Приклади їх включають ArrayList, LinkedListі т.д.

Якщо у вас була Listзмінна, і вам потрібно було знати, чи була вона ArrayList, ви можете зробити наступне:

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

Однак, якщо ви вважаєте, що вам потрібно зробити це, ви можете переосмислити свій підхід. У більшості випадків, якщо ви будете дотримуватися об'єктно-орієнтованих принципів, вам цього не потрібно буде робити. Звичайно, у кожному правилі є винятки.


3
Оператор instanceof визначає лише тип даних об'єкта, на який посилається змінна. Він не визначає тип даних фактичної ВАРІАБЛІ, як спочатку вимагали.
ГрантРобертсон

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

21
Не гарний метод ІМО. Що станеться, якщо я передаю якийсь довільний тип, який не визначений у вашому класі Typetester - наприклад у цьому рядку String?
Таш Пемхіва

6
@TashPemhiwa потім додайте String і Object до варіантів. Творчість та вирішення проблем - це найкраща перевага програмістів.
Като

8
Все-таки це може мати справу лише з фіксованим набором заздалегідь визначених класів (що перемагає мету орієнтації на об'єкт / поліморфізм) і лише дасть вам щось на зразок "невідомого класу" для об'єктів будь-якого іншого класу
Алгоман

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?

Це може статися. Я намагаюся проаналізувати Stringint, і я хотів би знати, чи моє Integer.parseInt(s.substring(a, b))виштовхує інт чи сміття, перш ніж спробувати його підбити.

До речі, це відомо як Рефлексія. Ось додаткова інформація з цього питання: http://docs.oracle.com/javase/tutorial/reflect/


14

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


2
Все, що нам потрібно, - це дійсний випадок використання.
Маркіз Лорн

Здається, найбільш ефективний підхід.
І.Тигер

13

Просто використовуйте:

.getClass().getSimpleName();

Приклад:

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

Вихід:

StringBuilder

1
Я пропоную зазначити, що це не працює, якщо randSBутримується NULL.
Василь Бурк

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 Так, я знаю, що це також не перевіряє примітивів.


6

Перша частина вашого питання безглузда. Немає обставин, за яких ви не знаєте тип примітивної змінної під час компіляції.

З другої частини, єдиною обставиною, що ви вже не знаєте, чи є змінною масив, якщо це Об'єкт. У такому випадку object.getClass().isArray()вам скажу.


5
Я міг би мати хеш-карту від рядка до об'єкта, помістити інт у цю хешмап і витягнути її назад. Єдине, що я знаю, це те, що це "об'єкт", і він міг би перевірити, що це за тип. Не кажучи, що це добре, просто кажу, що це можливо.
matty-d


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 перед викликом. Це все одно викине виняток, якщо при виклику немає значення, але порівняно із пов'язаним рішенням, це, безумовно, найпростіший спосіб зробити це

Я знаю, що це свого роду специфічне додаток, але оскільки це перший результат в Google для пошуку типу змінної з java (і враховуючи, що Tце свого роду змінна), я вважаю, що її слід включити



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
    }

}

1
Невелика підказка: Коли є питання , який вже 10 років і має> 10 відповідей, деякі з яких мають> 100 upvotes, то (не неможливо , але) дуже , дуже малоймовірно , що новий відповідь може додати що - то корисне ( в Зокрема, коли це просто фрагмент коду, який говорить "Ось, дивись, це щось друкує" ...)
Marco13

-4

громадський клас 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());

}

}

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.