Java - รับชื่อคลาสปัจจุบันหรือไม่


271

ทั้งหมดที่ฉันพยายามทำคือการได้รับชื่อคลาสปัจจุบันและ java ผนวกชื่อที่ไม่มีประโยชน์1 ดอลลาร์ต่อท้ายชื่อคลาสของฉัน ฉันจะกำจัดมันและคืนชื่อคลาสจริงได้อย่างไร

String className = this.getClass().getName();

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

8
ดังนั้นสิ่งที่คุณต้องการคือString className = getClass().getName().substring(0, getClass().getName().indexOf("$"))
josh.trow

9
ถ้าคุณได้รับแล้วเพราะชื่อของชั้นคือ$1 $1หากคุณคาดหวังอย่างอื่นให้ใช้thisในชั้นเรียนที่เหมาะสมแทนชั้นเรียนที่ไม่ถูกต้อง
เซเว่น

คำตอบ:


247

"$ 1" ไม่ใช่ "ไร้ประโยชน์" ถ้าคลาสของคุณไม่ระบุชื่อจะมีการต่อท้ายหมายเลข

หากคุณไม่ต้องการที่ชั้นเอง getEnclosingClass()แต่ระดับประกาศของมันแล้วคุณสามารถใช้ ตัวอย่างเช่น:

Class<?> enclosingClass = getClass().getEnclosingClass();
if (enclosingClass != null) {
  System.out.println(enclosingClass.getName());
} else {
  System.out.println(getClass().getName());
}

คุณสามารถย้ายสิ่งนั้นในวิธียูทิลิตี้แบบคงที่

แต่โปรดทราบว่านี่ไม่ใช่ชื่อคลาสปัจจุบัน คลาสที่ไม่ระบุชื่อเป็นคลาสที่แตกต่างจากคลาสที่ล้อมรอบ เคสมีความคล้ายคลึงกับคลาสภายใน


2
แต่ถ้าคลาสปิดล้อมเป็นคลาสภายในที่ไม่ระบุชื่อด้วย? คุณไม่ต้องรับคลาสที่ปิดล้อมซ้ำจนกว่ามันจะกลับnullมาและใช้nullคลาสสุดท้ายที่คุณได้รับมาใช่ไหม
Garret Wilson

231

ลอง,

String className = this.getClass().getSimpleName();

สิ่งนี้จะทำงานได้ตราบใดที่คุณไม่ได้ใช้วิธีคงที่


1
อันที่จริงไม่ได้ผล คำถามนี้บ่งชี้ว่าเขามีคลาสภายในที่ไม่ระบุชื่อและสำหรับกรณีนี้ getSimpleName () ส่งคืน""
vikingsteve

48
แม้ว่าสิ่งนี้จะไม่ตอบคำถาม แต่ตอนนี้โพสต์นี้อยู่ในผลลัพธ์อันดับต้น ๆ ของ "get class name java" บน google และดังนั้นจึงเป็นประโยชน์ต่อชุมชน
EdgeCaseBerg

6
มันจะส่งคืนชื่อโดยไม่มีแพ็คเกจเนมสเปซ สิ่งที่ดี!
Oleg Abrazhaev

31

ลองใช้นี้ หรือthis.getClass().getCanonicalName() this.getClass().getSimpleName()ถ้าเป็นคลาสที่ไม่ระบุชื่อใช้this.getClass().getSuperclass().getName()


จริงๆแล้วมันทำ ทั้งนี้ขึ้นอยู่กับ หากคุณพยายามที่จะรับชื่อของคลาสนามธรรมที่คุณใช้กับคลาสนิรนามนี่คือสิ่งที่คุณใช้
MirroredFate

สำหรับกรณีของเขา (คลาสนิรนาม) ชื่อธรรมดาว่างเปล่าชื่อ canconical เป็นโมฆะและ superclass คือ Object
Bozho

ใช่ใช่ไม่ใช่ สองคนแรกของฉันเดาได้แค่คนที่สาม แต่ถูกต้อง คลาสที่ไม่ระบุชื่อเป็นคลาสย่อยของคลาสที่ใช้ นั่นเป็นเหตุผลที่พวกเขาทำงาน ดังนั้นซูเปอร์คลาสคือคลาสนามธรรม
MirroredFate

แปลกไม่ได้เป็นคลาสที่ซุปเปอร์คลาสที่คุณกำลังสืบทอดมาจากไหน? ตัวจัดการไม่ได้สืบทอดจากชั้นเรียนของฉันมันเป็นเพียงสมาชิก
aryaxt

อืมมมมมมมมมมมมมมมมมมมมม. อีกครั้งอืมมฉันได้ทำการทดสอบแล้วและฉันก็ทราบว่าซุปเปอร์คลาสของคลาสนิรนามเป็นคลาสนามธรรม ฉันจะตรวจสอบตรรกะของฉันอีกครั้ง แต่เมื่อฉันได้รับผลลัพธ์ที่เหมาะสมฉันไม่คิดว่ามันเป็นฉันที่ทำผิด ....
MirroredFate

10

คุณสามารถใช้this.getClass().getSimpleName()เช่น:

import java.lang.reflect.Field;

public class Test {

    int x;
    int y;  

    public void getClassName() {
        String className = this.getClass().getSimpleName(); 
        System.out.println("Name:" + className);
    }

    public void getAttributes() {
        Field[] attributes = this.getClass().getDeclaredFields();   
        for(int i = 0; i < attributes.length; i++) {
            System.out.println("Declared Fields" + attributes[i]);    
        }
    }

    public static void main(String args[]) {

        Test t = new Test();
        t.getClassName();
        t.getAttributes();
    }
}

4

การรวมกันของทั้งสองคำตอบ พิมพ์ชื่อวิธีการด้วย:

Class thisClass = new Object(){}.getClass();
String className = thisClass.getEnclosingClass().getSimpleName();
String methodName = thisClass.getEnclosingMethod().getName();
Log.d("app", className + ":" + methodName);

3

คำตอบนี้จะล่าช้า แต่ฉันคิดว่ามีวิธีการทำเช่นนี้ในบริบทของคลาสตัวจัดการนิรนาม

สมมติว่า:

class A {
    void foo() {
        obj.addHandler(new Handler() {
            void bar() {
                String className=A.this.getClass().getName();
                // ...
            }
        });
    }
}

มันจะบรรลุผลลัพธ์เดียวกัน นอกจากนี้จริง ๆ แล้วค่อนข้างสะดวกสบายเนื่องจากทุกคลาสจะถูกกำหนดในเวลาคอมไพล์ดังนั้นจึงไม่มีความเสียหายแบบไดนามิก

ด้านบนนั้นถ้าคลาสนั้นซ้อนกันAจริง ๆเช่นถูกล้อมรอบด้วยBคลาสของ B สามารถรู้จักได้ง่ายในชื่อ:

B.this.getClass().getName()

2

ในตัวอย่างของคุณthisอาจหมายถึงอินสแตนซ์ของคลาสที่ไม่ระบุชื่อ Java ให้ชื่อแก่คลาสเหล่านั้นโดยผนวก a $numberกับชื่อของคลาสที่ล้อมรอบ


2
คลาสภายในที่ไม่ระบุชื่อมีชื่อว่า Outer $ Inner นี่จะเป็นคลาสที่ไม่ระบุชื่อ
Duncan McGregor

1

ฉันสมมติว่าสิ่งนี้เกิดขึ้นสำหรับคลาสที่ไม่ระบุชื่อ เมื่อคุณสร้างคลาสที่ไม่ระบุชื่อคุณจะสร้างคลาสที่ขยายคลาสที่มีชื่อของคุณ

วิธี "ทำความสะอาด" เพื่อให้ได้ชื่อที่คุณต้องการคือ:

หากคลาสของคุณเป็นคลาสภายในที่ไม่ระบุชื่อgetSuperClass()ควรให้คลาสที่คุณสร้างขึ้น หากคุณสร้างมันขึ้นมาจากส่วนต่อประสานมากกว่าที่คุณคุ้นเคย SOL ก็เป็นสิ่งที่ดีที่สุดgetInterfaces()สิ่งที่อาจทำให้คุณมีมากกว่าหนึ่งอินเตอร์เฟส

"การ hacky" วิธีที่เป็นเพียงการได้รับชื่อที่มีgetClassName()และใช้ regex $1เพื่อวาง


0

นี่คือตัวแปร Android แต่หลักการเดียวกันนี้สามารถใช้ใน Java ธรรมดาได้เช่นกัน

private static final String TAG = YourClass.class.getSimpleName();
private static final String TAG = YourClass.class.getName();

-3

ฉันพบสิ่งนี้ทำงานได้กับรหัสของฉัน แต่รหัสของฉันได้รับการเรียนออกจากอาร์เรย์ภายในสำหรับวง

String className="";

className = list[i].getClass().getCanonicalName();

System.out.print(className); //Use this to test it works

นี่ไม่ได้เพิ่มอะไรที่คำตอบอื่น ๆ ยังไม่ได้พูด ปัญหาลูป / อาร์เรย์ทั้งหมดไม่เกี่ยวข้อง นอกจากนี้คุณควรพิจารณาว่าการจัดรูปแบบโค้ดทำงานอย่างไรกับคำถาม / คำตอบ
Jonathon Reinhart

-4

Reflection APIs

มี Reflection API หลายตัวที่คืนคลาส แต่สามารถเข้าถึงได้หาก Class ได้รับไปแล้วไม่ว่าโดยตรงหรือโดยอ้อม

Class.getSuperclass()
     Returns the super class for the given class.

        Class c = javax.swing.JButton.class.getSuperclass();
        The super class of javax.swing.JButton is javax.swing.AbstractButton.

        Class.getClasses()

ส่งคืนคลาสสาธารณะอินเตอร์เฟสและ enums ทั้งหมดที่เป็นสมาชิกของคลาสรวมถึงสมาชิกที่สืบทอดมา

        Class<?>[] c = Character.class.getClasses();

ตัวละครประกอบด้วยสมาชิกสองคลาส Character.Subset และ
Character.UnicodeBlock

        Class.getDeclaredClasses()
         Returns all of the classes interfaces, and enums that are explicitly declared in this class.

        Class<?>[] c = Character.class.getDeclaredClasses();
     Character contains two public member classes Character.Subset and Character.UnicodeBlock and one private class

Character.CharacterCache

        Class.getDeclaringClass()
        java.lang.reflect.Field.getDeclaringClass()
        java.lang.reflect.Method.getDeclaringClass()
        java.lang.reflect.Constructor.getDeclaringClass()
     Returns the Class in which these members were declared. Anonymous Class Declarations will not have a declaring class but will

มีชั้นเรียนที่ล้อมรอบ

        import java.lang.reflect.Field;

            Field f = System.class.getField("out");
            Class c = f.getDeclaringClass();
            The field out is declared in System.
            public class MyClass {
                static Object o = new Object() {
                    public void m() {} 
                };
                static Class<c> = o.getClass().getEnclosingClass();
            }

     The declaring class of the anonymous class defined by o is null.

    Class.getEnclosingClass()
     Returns the immediately enclosing class of the class.

    Class c = Thread.State.class().getEnclosingClass();
     The enclosing class of the enum Thread.State is Thread.

    public class MyClass {
        static Object o = new Object() { 
            public void m() {} 
        };
        static Class<c> = o.getClass().getEnclosingClass();
    }
     The anonymous class defined by o is enclosed by MyClass.

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