Java - có được tên lớp hiện tại?


271

Tất cả những gì tôi đang cố gắng làm là lấy tên lớp hiện tại và java nối thêm $ 1 vô nghĩa vào cuối tên lớp của tôi. Làm thế nào tôi có thể thoát khỏi nó và chỉ trả lại tên lớp thực tế?

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

1
Bạn đang gọi nó ở đâu? Có phải từ bên trong một lớp bên trong vô danh? Bạn có thể thêm một số mã hiển thị chi tiết về định nghĩa của lớp và dòng này được gọi từ đâu không?
plainjimbo

8
Vì vậy, tất cả những gì bạn muốn làString className = getClass().getName().substring(0, getClass().getName().indexOf("$"))
josh.trow

9
Nếu bạn nhận được $1sau đó, bởi vì tên của lớp là $1. Nếu bạn mong đợi một cái gì đó khác, sử dụng thistrong lớp đúng thay vì sai.
ceving

Câu trả lời:


247

"$ 1" không phải là "vô nghĩa". Nếu lớp của bạn là ẩn danh, một số được thêm vào.

Nếu bạn không muốn lớp đó, nhưng lớp khai báo, thì bạn có thể sử dụng getEnclosingClass(). Ví dụ:

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

Bạn có thể di chuyển nó trong một số phương thức tiện ích tĩnh.

Nhưng lưu ý rằng đây không phải là tên lớp hiện tại. Lớp ẩn danh là lớp khác với lớp kèm theo của nó. Trường hợp tương tự cho các lớp bên trong.


2
Nhưng nếu lớp kèm theo cũng là lớp bên trong ẩn danh thì sao? Bạn không cần phải đệ quy lớp kèm theo cho đến khi nó trả về nullvà sử dụng nulllớp không phải cuối cùng mà bạn có?
Garret Wilson

231

Thử,

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

Điều này sẽ hoạt động miễn là bạn không sử dụng nó trong một phương thức tĩnh.


1
Trên thực tế, không có điều này sẽ không làm việc. Câu hỏi này cho biết anh ta có một lớp bên trong ẩn danh và trong trường hợp này, getSimpleName () trả về""
vikingsteve

48
Mặc dù điều này không trả lời được câu hỏi, bài đăng SO này hiện đang nằm trong kết quả hàng đầu cho "lấy tên lớp java" trên google, và vì vậy nó vẫn hữu ích cho cộng đồng.
EdgeCaseBerg

6
Nó sẽ trả về tên mà không có không gian tên gói. Tốt một!
Oleg Abrazhaev

31

Hãy thử sử dụng cái này this.getClass().getCanonicalName()hoặc this.getClass().getSimpleName(). Nếu đó là một lớp ẩn danh, hãy sử dụngthis.getClass().getSuperclass().getName()


Trên thực tế, nó làm. Tùy. Nếu bạn đang cố gắng để có được tên của lớp trừu tượng bạn đang thực hiện với một lớp ẩn danh, thì đây là những gì bạn sử dụng.
MirroredFate

đối với trường hợp của anh ta (lớp ẩn danh), tên đơn giản là trống, tên canconical là null và siêu lớp là Object.
Bozho

Vâng, vâng, không. Hai cái đầu tiên của tôi chỉ là phỏng đoán, tuy nhiên thứ ba là chính xác. Một lớp ẩn danh là một lớp con của lớp mà nó thực hiện. Đó là lý do tại sao họ làm việc. Vì vậy, siêu lớp là lớp trừu tượng.
MirroredFate

Lạ không phải là siêu hạng mà lớp bạn đang kế thừa? Handler không kế thừa lớp học của tôi, nó chỉ là một thành viên
aryaxt

Umm ... Tôi đã thử nghiệm điều này, và tôi nhận ra rằng siêu lớp của lớp ẩn danh là lớp trừu tượng. Tôi sẽ kiểm tra lại logic của mình ... nhưng khi tôi nhận được kết quả có ý nghĩa, tôi không nghĩ rằng chính tôi đã phạm sai lầm ....
MirroredFate

10

Bạn có thể sử dụng this.getClass().getSimpleName(), như vậy:

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

Sự kết hợp của cả hai câu trả lời. Cũng in một tên phương thức:

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

3

Câu trả lời này là muộn, nhưng tôi nghĩ có một cách khác để làm điều này trong bối cảnh của lớp xử lý ẩn danh.

hãy cùng nói nào:

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

nó sẽ đạt được kết quả tương tự ngoài ra, nó thực sự khá tiện lợi vì mỗi lớp được xác định tại thời gian biên dịch, do đó không có tính năng động nào bị hỏng.

ở trên, nếu lớp thực sự được lồng, tức là Athực sự được bao quanh bởi B, lớp B có thể dễ dàng được gọi là:

B.this.getClass().getName()

2

Trong ví dụ của bạn, thiscó lẽ đề cập đến một thể hiện lớp ẩn danh. Java đặt tên cho các lớp đó bằng cách thêm một $numbertên của lớp kèm theo.


2
Các lớp bên trong không ẩn danh được đặt tên là Outer $ Inside. Đây sẽ là một lớp ẩn danh.
Duncan McGregor

1

Tôi cho rằng điều này đang xảy ra đối với một lớp ẩn danh. Khi bạn tạo một lớp ẩn danh, bạn thực sự tạo một lớp mở rộng lớp có tên bạn có.

Cách "sạch" hơn để có được tên bạn muốn là:

Nếu lớp của bạn là một lớp bên trong ẩn danh, getSuperClass()sẽ cung cấp cho bạn lớp mà nó được tạo từ đó. Nếu bạn đã tạo nó từ một giao diện hơn là loại SOL vì điều tốt nhất bạn có thể làm làgetInterfaces() có thể cung cấp cho bạn nhiều hơn một giao diện.

Cách "hacky" là chỉ cần lấy tên getClassName()và sử dụng biểu thức chính quy để loại bỏ $1.


0

Đây là một biến thể của Android, nhưng nguyên tắc tương tự cũng có thể được sử dụng trong Java thuần túy.

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

-3

Tôi đã tìm thấy điều này để làm việc cho mã của mình ,, tuy nhiên mã của tôi đang đưa lớp ra khỏi một mảng trong một vòng lặp for.

String className="";

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

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

Điều này không thêm bất cứ điều gì mà bất kỳ câu trả lời nào khác chưa nói. Toàn bộ vấn đề vòng lặp / mảng là không liên quan. Ngoài ra, bạn nên xem xét cách thức định dạng mã hoạt động trên các câu hỏi / câu trả lời.
Jonathon Reinhart

-4

API phản chiếu

Có một số API phản chiếu trả về các lớp nhưng chúng chỉ có thể được truy cập nếu một Lớp đã được lấy trực tiếp hoặc gián tiếp.

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

Trả về tất cả các lớp công khai, giao diện và enum là thành viên của lớp bao gồm các thành viên được kế thừa.

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

Nhân vật chứa hai lớp thành viên Character.Subset và
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

Nhân vật.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

có một lớp học kèm theo.

        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
Bạn có biết rằng bạn đã đăng câu trả lời của mình dưới dạng một khối mã nguyên khối không? Các tuyên bố không nên được định dạng như trích dẫn mã ...
Massimiliano Kraus
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.