คุณรู้จักตัวแปรชนิดใน java ได้อย่างไร


152

สมมติว่าฉันประกาศตัวแปร:

String a = "test";

และฉันต้องการที่จะรู้ว่ามันคือประเภทใดเช่นผลลัพธ์ที่ควรจะเป็นjava.lang.Stringฉันจะทำอย่างไร


1
คุณสนใจประเภทของตัวแปรหรือไม่? หรือคุณดูแลเกี่ยวกับประเภทของค่า ? เนื่องจากประเภทของตัวแปรไม่สามารถรับได้ง่าย (ที่จริงแล้วมันเป็นไปไม่ได้เลยสำหรับตัวแปรในระบบและต้องการการสะท้อนกลับสำหรับฟิลด์)
Joachim Sauer

8
@Paul: พิจารณาObject o = "o";- ประเภทของตัวแปรคือ Object ชนิดของค่าคือ String
Michael Borgwardt

2
@ Paul ในList<String> l = new ArrayList<String>();ประเภทของตัวแปรที่มีชนิดของค่าที่เป็นList<String> ArrayList<String>
Ben Lings

1
@Ben Lings ประเภทของตัวแปรคือ java.util.ArrayList และประเภทของค่าคือ java.util.ArrayList
Ajay Takur

1
@AjayThakur - เป็นความแตกต่างระหว่างประเภทคอมไพล์เวลา (คงที่) และประเภทรันไทม์ (ไดนามิก)
Ben Lings

คำตอบ:


269
a.getClass().getName()

16
ที่จะให้ประเภทของค่า ไม่จำเป็นต้องเป็นประเภทของตัวแปร
Joachim Sauer

7
ฉันเพิ่งคิดว่าเป็นสิ่งที่ OP กำลังมองหาจริงๆเนื่องจากการประกาศของaค่อนข้างชัดเจนในเวลารวบรวม
มาร์ติน

4
นั่นจะใช้ได้ถ้าประเภทนั้นไม่ใช่แบบดั้งเดิม ... ถ้าชนิดนั้นเป็น int จะรู้ได้อย่างไร?
Miguel Ribeiro

5
@Miguel: ตั้งแต่วิธีเดียวที่คุณสามารถจัดการintค่าอยู่ในintตัวแปรมีวิธีการเขียนโค้ดที่จับไม่intคุ้มค่าและไม่ทราบชนิดที่ เรื่องนี้แตกต่างกันในกรณีที่คุณใช้กระดาษห่อหุ้มIntegerแต่รหัสของคำตอบนี้ใช้งานได้อีกครั้ง
Joachim Sauer

1
นี่ไม่ใช่ความจริงสำหรับประเภทดั้งเดิม
Mehdi

37

หากคุณต้องการชื่อให้ใช้วิธีการของ Martin หากคุณต้องการทราบว่าเป็นตัวอย่างของคลาสที่ต้องการหรือไม่:

boolean b = a instanceof String


15
คุณไม่ได้มาร์ตินด้วยเหรอ? :)
seokhoonlee

อื่น ๆ ที่มาร์ติน ... ฮ่า ๆ ;)
chankruze

รหัสDouble a = 1d; boolean b = a instanceof String;นี้จะทำให้เกิดข้อผิดพลาดerror: incompatible types: Double cannot be converted to String
Alex78191

35

ฉันต้องการขยายคำตอบของ Martin ที่นั่น ...

วิธีแก้ปัญหาของเขาค่อนข้างดี แต่มันสามารถปรับแต่งเพื่อให้ "ตัวแปรประเภท" ใด ๆ สามารถพิมพ์เช่นนั้น (จริง ๆ แล้วเป็นประเภทคุ้มค่าเพิ่มเติมในหัวข้อ ) ที่กล่าวว่า "ปรับแต่ง" อาจเป็นคำที่แข็งแกร่งสำหรับเรื่องนี้ มันอาจจะมีประโยชน์

โซลูชั่นมาร์ติน:

a.getClass().getName()

อย่างไรก็ตามหากคุณต้องการให้มันทำงานกับทุกสิ่งคุณสามารถทำได้:

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

ในกรณีนี้ดั้งเดิมจะถูกห่อด้วย Wrapper คุณจะได้รับวัตถุของดั้งเดิมในกรณีนั้น

ตัวฉันเองใช้มันอย่างนี้

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

ใช้ Generics:

public static <T> String nameOf(T o) {
    return o.getClass().getSimpleName();
}

น่าสนใจ ฉันเพิ่งลองรหัสของคุณใน: System.out.println (((Object) Integer.parseInt ("12")) .getClass (). getSimpleName ()); และมันใช้งานได้! \ o /
shevy

31

ฉันเรียนรู้จาก Search Engine (ภาษาอังกฤษของฉันแย่มากดังนั้นรหัส ... ) วิธีรับประเภทของตัวแปร? ของขึ้น:

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

วิธีนี้:

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

ตอนนี้ตัวอย่าง:

Object o = 1;
o.getClass().getSimpleName();
value:Integer

3

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

จริงๆแล้วสำหรับฉันมันเป็นไปไม่ได้เลยที่a.xxx().yyy()วิธีการใด ๆให้คำตอบที่ถูกต้องเนื่องจากคำตอบจะแตกต่างกันในวัตถุเดียวกันแน่นอนตามบริบทที่คุณเรียกวิธีนี้ ...

ดังที่ teehoo กล่าวหากคุณทราบว่ารวบรวมรายการประเภทที่กำหนดไว้เพื่อทดสอบคุณสามารถใช้ instanceof แต่คุณจะได้รับคลาสย่อยกลับมาเป็นจริง ...

ทางออกที่เป็นไปได้ข้อหนึ่งก็คือการสร้างแรงบันดาลใจให้ตัวเองจากการนำไปใช้งานjava.lang.reflect.Fieldและสร้างFieldคลาสของคุณเองแล้วประกาศตัวแปรท้องถิ่นทั้งหมดของคุณเป็นการFieldใช้งานแบบกำหนดเอง... แต่คุณควรหาวิธีแก้ปัญหาอื่นดีกว่า พิมพ์ไม่ใช่แค่ประเภทค่า?


สำหรับ"แต่คุณจะได้รับคลาสย่อยที่คืนค่าเป็นจริง ... "ฉันคิดว่าคุณหมายถึง"แต่คุณจะได้รับคลาสผู้ปกครองที่คืนค่าจริง ... "ด้วยใช่ไหม
skomisa

3

ใช้คุณสมบัติการใช้งานมากเกินไปของจาวา

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 ...

}

8
Java ไม่มีแนวคิดของการใช้งานตัวดำเนินการมากเกินไปนี่เป็นวิธีการทำงานหนักมากเกินไป
nicoschl

2

ฉันคิดว่าเรามีวิธีแก้ปัญหาหลายอย่างที่นี่:

  • อินสแตนซ์ของอาจเป็นวิธีแก้ปัญหา

ทำไม? ใน Java ทุกคลาสนั้นได้รับการสืบทอดมาจากคลาส Object เอง ดังนั้นหากคุณมีตัวแปรและคุณต้องการทราบชนิดของมัน คุณสามารถใช้ได้

  • System.out.println (((Object) ฉ) .getClass () getName ().);

หรือ

  • Integer.class.isInstance (1985); // ให้ความจริง

หรือ

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

สิ่งนี้จะทำให้เรา:

  1. FALSE
  2. TRUE

ค้นหาข้อมูลเพิ่มเติมได้ที่นี่: วิธีการกำหนดประเภทดั้งเดิมของตัวแปรดั้งเดิม

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

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