Java - отримаєте назву поточного класу?


271

Все, що я намагаюся зробити, - це отримати ім’я поточного класу, і java додає марний нерозумний $ 1 до кінця імені мого класу. Як я можу позбутися цього і повернути лише власне ім’я класу?

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

1
Куди ти це кличеш? Це з анонімного внутрішнього класу? Чи можете ви додати ще якийсь код, який показує деталі щодо визначення класу та звідки цей рядок викликається?
звичайний

8
Отже, все, що вам потрібно,String className = getClass().getName().substring(0, getClass().getName().indexOf("$"))
josh.trow

9
Якщо ви отримаєте $1тоді, тому що назва класу $1. Якщо ви очікуєте чогось іншого, використовуйте thisправильний клас замість неправильного.
ceving

Відповіді:


247

"$ 1" не є "марним безглуздим". Якщо ваш клас анонімний, додається номер.

Якщо ви не хочете сам клас, а його декларуючий клас, тоді ви можете використовувати getEnclosingClass(). Наприклад:

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

Ви можете перемістити це в якомусь методі статичної корисності.

Але зауважте, що це не поточна назва класу. Анонімний клас - інший клас, ніж клас, що додає. Випадок подібний для внутрішніх класів.


2
Але що робити, якщо додаючий клас також є анонімним внутрішнім класом? Чи не потрібно рекурсивно отримувати клас, що додає, доки він не повернеться null, і використовувати останній неклас, який nullви отримали?
Гаррет Вілсон

231

Спробуйте,

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

Це буде працювати до тих пір, поки ви не використовуєте його в статичному методі.


1
Насправді, ні це не спрацює. Це запитання вказує, що він має анонімний внутрішній клас, і для цього випадку getSimpleName () повертається""
vikingsteve

48
Незважаючи на те, що це не дає відповіді на запитання, ця публікація в даний час є найкращими результатами для "отримати назву класу java" в Google, і тому вона все ще корисна для громади.
EdgeCaseBerg

6
Він поверне ім'я без простору імен пакетів. Хороший!
Олег Абражаєв

31

Спробуйте скористатися цим this.getClass().getCanonicalName()або this.getClass().getSimpleName(). Якщо це анонімний клас, використовуйтеthis.getClass().getSuperclass().getName()


Власне, це і є. Залежно. Якщо ви намагаєтесь отримати ім’я абстрактного класу, який ви реалізуєте, з анонімним класом, саме цим ви користуєтеся.
MirroredFate

для його випадку (анонімний клас) просте ім’я порожнє, канонічне ім'я - нульове, а надклас - "Об'єкт".
Божо

Так, так, ні. Мої перші два були лише здогадами, третя, однак, правильно. Анонімний клас - це підклас класу, який він реалізує. Тому вони працюють. Таким чином, суперклас - це абстрактний клас.
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 дає ім'я цим класам, додаючи $numberдо імені класу, що додається.


2
Неанонімні внутрішні класи називаються Зовнішні $ Внутрішні. Це буде анонімний клас.
Дункан МакГрегор

1

Я припускаю, що це відбувається для анонімного класу. Коли ви створюєте анонімний клас, ви фактично створюєте клас, який розширює клас, ім'я якого ви отримали.

"Чистіший" спосіб отримати потрібне ім'я:

Якщо ваш клас є анонімним внутрішнім класом, getSuperClass()слід дати вам клас, з якого він створений. Якщо ви створили його з інтерфейсу, ніж ви на зразок SOL, тому що найкраще, що ви можете зробити, це getInterfaces()може дати вам більше одного інтерфейсу.

"Хакі" спосіб - просто отримати ім'я getClassName()та використати регулярний вираз для скидання $1.


0

Ось варіант Android, але той самий принцип можна використовувати і в звичайній Java.

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

-3

Я виявив, що це працює для мого коду ,, однак мій код виводить клас з масиву в циклі for.

String className="";

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

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

Це не додає нічого, чого жоден з інших відповідей ще не сказав. Вся проблема циклу / масиву не має значення. Також слід вивчити, як працює форматування коду на питання / відповіді.
Джонатан Райнхарт

-4

API відображення

Існує кілька API відбиття, які повертають класи, але до них можна отримати доступ лише в тому випадку, якщо клас вже отриманий прямо чи опосередковано.

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

Повертає всі загальнодоступні класи, інтерфейси та перерахунки, які є членами класу, включаючи спадкоємні члени.

        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
Чи знаєте ви, що ви розмістили свою відповідь як загальний монолітний блок коду? Висловлювання не слід форматувати як котирування коду ...
Массіміліано Краус
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.