Java - geçerli sınıf adını almak?


271

Yapmaya çalıştığım tek şey geçerli sınıf adını almak ve java sınıf adımın sonuna anlamsız bir $ 1 ekler . Nasıl kurtulabilir ve sadece gerçek sınıf adını döndürebilirim?

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

1
Bunu nereye çağırıyorsun? İsimsiz bir iç sınıfın içinden mi geliyor? Sınıfın tanımı ve bu hattın nereden çağrıldığı ile ilgili ayrıntıları gösteren bir kod daha ekleyebilir misiniz?
plainjimbo

8
Yani, tek istediğinString className = getClass().getName().substring(0, getClass().getName().indexOf("$"))
josh.trow

9
Eğer alırsanız $1, çünkü sınıfın adı $1. Başka bir şey bekliyorsanız this, yanlış sınıf yerine doğru sınıfta kullanın.
ceving

Yanıtlar:


247

"1 $", "anlamsız anlamsızlık" değildir. Sınıfınız anonim ise, bir sayı eklenir.

Sınıfın kendisini istemez, ancak sınıfını bildirirseniz kullanabilirsiniz getEnclosingClass(). Örneğin:

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

Bunu bazı statik yardımcı yöntemlerde taşıyabilirsiniz.

Ancak bunun geçerli sınıf adı olmadığını unutmayın. Anonim sınıf, kapalı sınıfından farklı bir sınıftır. Dava iç sınıflar için benzerdir.


2
Peki ya kapalı sınıf aynı zamanda anonim bir iç sınıfsa? Dönene kadar çevreleyen sınıfı tekrar tekrar almanız nullve aldığınız son nullsınıf dışı öğeyi kullanmanız gerekmez mi?
Garret Wilson

231

Deneyin,

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

Bu, statik bir yöntemde kullanmadığınız sürece çalışacaktır.


1
Aslında hayır, bu işe yaramaz. Bu soru anonim bir iç sınıfa sahip olduğunu gösterir ve bu durumda getSimpleName () döndürür""
vikingsteve

48
Bu soruya cevap vermese de, bu SO yayını şu anda Google'da "get class name java olsun" için en iyi sonuçlardadır ve bu nedenle topluluk için hala yararlıdır.
EdgeCaseBerg

6
Paket ad alanı olmadan adı döndürür. İyi bir!
Oleg Abrazhaev

31

Bunu kullanmayı deneyin this.getClass().getCanonicalName()veya this.getClass().getSimpleName(). Anonim bir sınıfsa,this.getClass().getSuperclass().getName()


Aslında öyle. Bağlı. Anonim bir sınıfla uyguladığınız soyut sınıfın adını almaya çalışıyorsanız, bunu kullanırsınız.
MirroredFate

durumu (anonim sınıf) için basit ad boş, kurallı ad boş ve üst sınıf Nesne'dir.
Bozho

Evet, evet, hayır. Benim ilk ikisi sadece tahminlerdi, üçüncüsü ise doğru. Anonim sınıf uyguladığı sınıfın bir alt sınıfıdır. Bu yüzden çalışıyorlar. Böylece, üst sınıf soyut sınıftır.
MirroredFate

Garip olduğunuz süper sınıf, garip değil mi? İşleyici sınıfımdan miras almıyor, sadece bir üye
aryaxt 21

Hmm ... Bunu test ettim ve anonim sınıfın üst sınıfının soyut sınıf olduğunu anladım. Mantığımı tekrar kontrol edeceğim ... ama mantıklı bir sonuç elde ettiğim için, hatayı yapan benim olduğunu sanmıyorum ....
MirroredFate

10

Şöyle kullanabilirsiniz 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

Her iki cevabın kombinasyonu. Ayrıca bir yöntem adı yazdırır:

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

3

bu cevap geç, ama anonim işleyici sınıfı bağlamında bunu yapmanın başka bir yolu olduğunu düşünüyorum.

diyelimki:

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

aynı sonucu elde edecek. ek olarak, her sınıf derleme zamanında tanımlandığından aslında oldukça rahattır, bu nedenle hiçbir dinamiklik zarar görmez.

bunun üzerinde, eğer sınıf gerçekten iç içe geçmişse, yani Aaslında içine alınmışsa, BB sınıfı kolayca şu şekilde bilinir:

B.this.getClass().getName()

2

Örneğinizde, thismuhtemelen anonim bir sınıf örneğini ifade eder. Java $number, ekli sınıfın adına a ekleyerek bu sınıflara bir ad verir .


2
Anonim olmayan iç sınıflar Outer $ Inner olarak adlandırılır. Bu isimsiz bir sınıf olacak.
Duncan McGregor

1

Bunun isimsiz bir sınıf için gerçekleştiğini varsayıyorum. Anonim bir sınıf oluşturduğunuzda, aslında adını aldığınız sınıfı genişleten bir sınıf oluşturursunuz.

İstediğiniz adı almanın "temiz" yolu:

Sınıfınız anonim bir iç sınıfsa, getSuperClass()size yaratıldığı sınıfı vermelidir. Bunu bir çeşit SOL'dan oluşturduysanız, yapabileceğiniz en iyi şey getInterfaces()size birden fazla arabirim verebilmenizdir.

"Hacky" yolu sadece adını almak getClassName()ve bırakmak için bir normal ifade kullanmaktır $1.


0

İşte bir Android varyantı, ancak aynı ilke düz Java'da da kullanılabilir.

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

-3

Kodum için çalışmak için buldum, ancak benim kod sınıf bir for döngüsü içinde bir dizi dışarı alıyorum.

String className="";

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

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

Bu, diğer cevapların daha önce söylemediği hiçbir şey eklemez. Tüm döngü / dizi sorunu önemsizdir. Ayrıca, kod biçimlendirmesinin sorular / yanıtlar üzerinde nasıl çalıştığına da bakmalısınız.
Jonathon Reinhart

-4

Yansıma API'ları

Sınıfları döndüren birkaç Yansıma API'si vardır, ancak bunlara yalnızca bir Sınıf doğrudan veya dolaylı olarak önceden alınmışsa erişilebilir.

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

Devralınan üyeler dahil sınıfın üyesi olan tüm ortak sınıfları, arabirimleri ve numaralandırmaları döndürür.

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

Karakter iki üye sınıfı Character.Subset ve
Character.UnicodeBlock içerir.

        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

kapalı bir sınıfa sahip olmak.

        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
Cevabınızı toplam monolitik bir kod bloğu olarak yayınladığınızın farkında mısınız? İfadeler kod tırnak işareti olarak biçimlendirilmemelidir ...
Massimiliano Kraus
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.