Java - dapatkan nama kelas saat ini?

271

Yang saya coba lakukan hanyalah mendapatkan nama kelas saat ini, dan java menambahkan $ 1 yang tidak masuk akal ke akhir nama kelas saya. Bagaimana saya bisa menghilangkannya dan hanya mengembalikan nama kelas yang sebenarnya?

String className = this.getClass().getName();
aryaxt
sumber
1
Di mana Anda memanggil ini? Apakah itu dari dalam kelas batin anonim? Bisakah Anda menambahkan beberapa kode lagi yang memperlihatkan detail tentang definisi kelas dan dari mana baris ini dipanggil?
plainjimbo
8
Jadi, yang Anda inginkan adalahString className = getClass().getName().substring(0, getClass().getName().indexOf("$"))
josh.trow
9
Jika Anda mendapatkannya $1, karena nama kelasnya $1. Jika Anda mengharapkan sesuatu yang lain, gunakan thisdi kelas yang benar dan bukan yang salah.
ceving

Jawaban:

247

"$ 1" bukan "tidak berguna tidak berguna". Jika kelas Anda anonim, nomor ditambahkan.

Jika Anda tidak ingin kelas itu sendiri, tetapi kelas deklarasinya, maka Anda dapat menggunakannya getEnclosingClass(). Sebagai contoh:

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

Anda dapat memindahkannya dalam beberapa metode utilitas statis.

Tetapi perhatikan bahwa ini bukan nama kelas saat ini. Kelas anonim adalah kelas yang berbeda dari kelas yang dilampirkan. Kasingnya serupa untuk kelas dalam.

Bozho
sumber
2
Tetapi bagaimana jika kelas penutup juga merupakan kelas batin anonim? Tidakkah Anda harus secara rekursif mendapatkan kelas penutup sampai kembali null, dan menggunakan non- nullkelas terakhir yang Anda dapatkan?
Garret Wilson
231

Mencoba,

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

Ini akan berfungsi selama Anda tidak menggunakannya dalam metode statis.

jesg
sumber
1
Sebenarnya, tidak ada ini tidak akan berhasil. Pertanyaan ini menunjukkan ia memiliki kelas dalam anonim, dan untuk kasus ini, getSimpleName () kembali""
vikingsteve
48
Meskipun ini tidak menjawab pertanyaan, pos SO ini saat ini berada di hasil teratas untuk "get java name class" di google, dan karenanya masih bermanfaat bagi komunitas.
EdgeCaseBerg
6
Ini akan mengembalikan nama tanpa namespace paket. Bagus
Oleg Abrazhaev
31

Coba gunakan ini this.getClass().getCanonicalName()atau this.getClass().getSimpleName(). Jika ini kelas anonim, gunakanthis.getClass().getSuperclass().getName()

Mirrored Fate
sumber
Sebenarnya itu benar. Tergantung. Jika Anda mencoba untuk mendapatkan nama kelas abstrak yang Anda laksanakan dengan kelas anonim, inilah yang Anda gunakan.
MirroredFate
untuk kasusnya (kelas anonim), nama sederhana kosong, nama kanonik nol dan superclass adalah Object.
Bozho
Ya, ya, tidak. Dua yang pertama saya hanya menebak, yang ketiga, bagaimanapun, benar. Kelas anonim adalah subkelas dari kelas yang diterapkannya. Itu sebabnya mereka bekerja. Jadi, superclass adalah kelas abstrak.
MirroredFate
Aneh bukan kelas super dari kelas yang Anda warisi? Handler tidak mewarisi dari kelas saya, itu hanya anggota
aryaxt
Umm ... Saya telah menguji ini, dan saya mendapatkan bahwa superclass dari kelas anonim adalah kelas abstrak. Saya akan memeriksa ulang logika saya ... tetapi karena saya mendapatkan hasil yang masuk akal, saya tidak berpikir itu saya yang telah membuat kesalahan ....
MirroredFate
10

Anda dapat menggunakan this.getClass().getSimpleName(), seperti:

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();
    }
}
Karuna
sumber
4

Kombinasi kedua jawaban. Juga mencetak nama metode:

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

jawaban ini terlambat, tetapi saya pikir ada cara lain untuk melakukan ini dalam konteks kelas handler anonim.

Katakanlah:

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

itu akan mencapai hasil yang sama. Selain itu, sebenarnya cukup nyaman karena setiap kelas didefinisikan pada waktu kompilasi, jadi tidak ada dinamika yang rusak.

di atas itu, jika kelas benar-benar bersarang, yaitu Asebenarnya tertutup oleh B, kelas B dapat dengan mudah dikenal sebagai:

B.this.getClass().getName()
Jason Hu
sumber
2

Dalam contoh Anda, thismungkin merujuk ke instance kelas anonim. Java memberi nama untuk kelas-kelas itu dengan menambahkan a $numberke nama kelas terlampir.

tonio
sumber
2
Kelas dalam non-anonim diberi nama Outer $ Inner. Ini akan menjadi kelas anonim.
Duncan McGregor
1

Saya berasumsi ini terjadi untuk kelas anonim. Saat Anda membuat kelas anonim, Anda benar-benar membuat kelas yang memperluas kelas yang namanya Anda dapatkan.

Cara "bersih" untuk mendapatkan nama yang Anda inginkan adalah:

Jika kelas Anda adalah kelas dalam anonim, getSuperClass()harus memberi Anda kelas dari mana ia diciptakan. Jika Anda membuatnya dari antarmuka daripada SOL, karena yang terbaik yang dapat Anda lakukan adalah getInterfaces()memberi Anda lebih dari satu antarmuka.

Cara "hacky" adalah hanya dengan mendapatkan nama getClassName()dan menggunakan regex untuk menjatuhkan $1.

kebenaran
sumber
0

Berikut adalah varian Android, tetapi prinsip yang sama dapat digunakan di Jawa juga.

private static final String TAG = YourClass.class.getSimpleName();
private static final String TAG = YourClass.class.getName();
Ako
sumber
-3

Saya menemukan ini berfungsi untuk kode saya ,, namun kode saya mendapatkan kelas dari array dalam for loop.

String className="";

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

System.out.print(className); //Use this to test it works
hransom
sumber
Ini tidak menambahkan apa pun yang belum dijawab oleh jawaban lain mana pun. Seluruh masalah loop / array tidak relevan. Anda juga harus melihat bagaimana pemformatan kode berfungsi pada pertanyaan / jawaban.
Jonathon Reinhart
-4

API Refleksi

Ada beberapa API Refleksi yang mengembalikan kelas tetapi ini hanya dapat diakses jika Kelas telah diperoleh secara langsung atau tidak langsung.

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

Mengembalikan semua kelas publik, antarmuka, dan enum yang merupakan anggota kelas termasuk anggota yang diwarisi.

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

Karakter berisi dua kelas anggota Character.Subset dan
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

memiliki kelas penutup.

        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.
arunkumar sambu
sumber
2
Apakah Anda sadar bahwa Anda memposting jawaban sebagai blok kode monolitik total? Pernyataan tidak boleh diformat sebagai tanda kutip kode ...
Massimiliano Kraus