จะตรวจสอบชนิดของตัวแปรใน Java ได้อย่างไร?


120

ฉันจะตรวจสอบได้อย่างไรว่าตัวแปรของฉันเป็น int อาร์เรย์คู่ ฯลฯ ...

แก้ไข: ตัวอย่างเช่นฉันจะตรวจสอบว่าตัวแปรเป็นอาร์เรย์ได้อย่างไร มีฟังก์ชั่นบางอย่างในการทำเช่นนี้หรือไม่?


ไปดูที่สะท้อน API
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
อินสแตนซ์ของตัวดำเนินการกำหนดประเภทข้อมูลของอ็อบเจ็กต์ที่อ้างถึงโดยตัวแปรเท่านั้น ไม่ได้กำหนดประเภทข้อมูลของ VARIABLE จริงตามที่ร้องขอในตอนแรก
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 );

21
ไม่ใช่วิธีการที่ดี IMO จะเกิดอะไรขึ้นถ้าฉันส่งผ่านประเภทตามอำเภอใจที่ไม่ได้กำหนดไว้ในคลาส Typetester ของคุณ - ตัวอย่างเช่นในสตริงอินสแตนซ์นี้
Tash Pemhiwa

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ถูกประกาศเป็นหรือส่งต่อมาจะไม่มีผลต่อผลลัพธ์ของตัวดำเนินการอินสแตนซ์

ฉันเอาข้อมูลนี้มาจาก: คุณรู้ประเภทตัวแปรใน java ได้อย่างไร?

สิ่งนี้สามารถเกิดขึ้นได้ ฉันกำลังพยายามแยกวิเคราะห์ a Stringเป็น int และฉันอยากรู้ว่าฉันInteger.parseInt(s.substring(a, b))กำลังเตะ int หรือขยะก่อนที่ฉันจะพยายามสรุป

โดยวิธีนี้เรียกว่าการสะท้อนกลับ ข้อมูลเพิ่มเติมเกี่ยวกับหัวข้อนี้มีดังนี้: http://docs.oracle.com/javase/tutorial/reflect/


14

คุณสามารถทำงานกับ Integer แทน int, Double แทนที่จะเป็น double เป็นต้น (คลาสดังกล่าวมีอยู่สำหรับประเภทดั้งเดิมทั้งหมด) จากนั้นคุณอาจใช้อินสแตนซ์ของตัวดำเนินการเช่นif(var instanceof Integer){...}


2
สิ่งที่เราต้องการคือกรณีการใช้งานที่ถูกต้อง
Marquis of Lorne

ดูเหมือนเป็นแนวทางที่มีประสิทธิภาพที่สุด
I.Tyger

13

เพียงใช้:

.getClass().getSimpleName();

ตัวอย่าง:

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

เอาท์พุท:

StringBuilder

1
ฉันขอแนะนำให้สังเกตว่าสิ่งนี้ไม่ได้ผลหากrandSBถือเป็น NULL
Basil Bourque

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

วิธีนี้คุณไม่จำเป็นต้องมีวิธีการที่มากเกินไป ฉันคิดว่าเป็นแนวทางปฏิบัติที่ดีในการใช้คอลเลกชันบนอาร์เรย์เนื่องจากประโยชน์เพิ่มเติม ต้องบอกว่าฉันไม่รู้วิธีตรวจสอบประเภทอาร์เรย์ อาจมีใครสามารถปรับปรุงโซลูชันนี้ได้ หวังว่านี่จะช่วยได้!

ปล. ใช่ฉันรู้ว่าสิ่งนี้ไม่ได้ตรวจสอบความเป็นดั้งเดิมเช่นกัน


6

ส่วนแรกของคำถามของคุณไม่มีความหมาย ไม่มีสถานการณ์ใดที่คุณไม่ทราบประเภทของตัวแปรดั้งเดิมในเวลาคอมไพล์

มาถึงส่วนที่สองซึ่งเป็นสถานการณ์เดียวที่คุณยังไม่รู้ว่าตัวแปรเป็นอาร์เรย์หรือไม่ถ้าเป็น Object กรณีobject.getClass().isArray()ไหนจะบอก.


5
ฉันสามารถมีแฮชแมปจากสตริงไปยังวัตถุใส่ int ในแฮชแมปนั้นแล้วดึงกลับออกมา สิ่งเดียวที่ฉันรู้คือมันเป็น "วัตถุ" และอาจต้องตรวจสอบว่าเป็นประเภทใด ไม่ได้บอกว่ามันดีแค่บอกว่าเป็นไปได้
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ก่อนที่จะโทร สิ่งนี้จะยังคงให้ข้อยกเว้นหาก out เป็นโมฆะเมื่อถูกเรียก แต่เมื่อเทียบกับโซลูชันที่เชื่อมโยงแล้วนี่เป็นวิธีที่ง่ายที่สุดในการทำเช่นนี้

ฉันรู้ว่านี่เป็นแอปพลิเคชันเฉพาะประเภทหนึ่ง แต่เนื่องจากนี่เป็นผลลัพธ์แรกใน google สำหรับการค้นหาประเภทของตัวแปรด้วย java (และเนื่องจากTเป็นตัวแปรชนิดหนึ่ง) ฉันจึงรู้สึกว่าควรรวมไว้ด้วย


0

คุณสามารถตรวจสอบได้อย่างง่ายดายโดยใช้Java.lang.Class.getSimpleName()วิธีการเฉพาะเมื่อตัวแปรมีชนิดที่ไม่ใช่ดั้งเดิม มันใช้ไม่ได้กับประเภทดั้งเดิม int, long เป็นต้น

อ้างอิง - นี่คือลิงค์ Oracle docs


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

}

}

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.