Получите полное имя класса в Java, Class.forName

Я хочу распознать тип класса из строки, заданной через командную строку. Например, args[0] = "Integer",

Сейчас делаю так:

Class<?> cls = Class.forName(args[0]);

Но я получаю "java.lang.ClassNotFoundException: Integer"

Я читал, что мне нужно использовать полное имя класса в forName(), так как я могу получить строку «java.lang.Integer» из строки «Integer» или «java.util.ArrayList " из "ArrayList" и т. д.?

Ну, такие имена, как Integer и ArrayList, по своей сути неоднозначны. Как он должен знать, что вы имеете в виду java.lang.Integer, а не some.other.coolpackage.Integer?

Sweeper 27.11.2022 17:03

Значит, это невозможно? что, если я хочу получить полное имя класса, который есть в моем пакете? (при условии, что вы не знаете имя пути)

Matteo Rigat 27.11.2022 17:05

Ну я этого не говорил. Если вы можете придумать некоторые правила (о чем я просил в своем комментарии), которые отличают классы, которые вы действительно хотите найти, от любого другого класса, который может существовать, тогда вы можете реализовать эти правила.

Sweeper 27.11.2022 17:08

«Что, если я хочу получить полное имя класса, который есть в моем пакете?» Я не уверен, что вы имеете в виду. Если вы знаете, что он находится «в вашем пакете», то вы знаете, в каком пакете он находится, поэтому вы можете вычислить полное доменное имя, верно? У вас есть объект Class? Если да, то просто делайте getName().

Sweeper 27.11.2022 17:14

У меня есть это упражнение ... «напишите класс, чей main получает имя класса из командной строки и печатает все методы, которые можно вызвать для экземпляра переданного класса», я должен предположить, что у меня есть полное имя класса?

Matteo Rigat 27.11.2022 17:35

Да, я думаю, что разумно предположить, что ввод является полным доменным именем класса.

Sweeper 27.11.2022 17:41
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
6
120
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В Java String, Integer или даже BufferedInputStream — это бессмысленные слова, определенные программистами. При работе Java требуется полное имя, чтобы можно было отличить java.lang.String, например, от kotlin.String (другой язык, который также работает на JVM).

Вот почему java.lang.String — это не только имя, но и указывает JVM на пакет и, что более важно, эти пакеты представлены в файловой структуре.

Вот почему использование имен классов является недопустимым синтаксисом в Java, если только класс не находится в том же пакете (в этом случае Java может найти его с помощью вашего текущего объявления пакета) или если в верхней части есть импорт (что обеспечит Java полностью квалифицированное имя для ссылки)

Короче говоря, если у вас нет набора правил, в которых вы можете динамически предоставлять полное имя на основе короткого имени, вы мало что можете сделать.

Вот короткая демонстрация крошечного скрипта, который будет проходить через пару общих пакетов, чтобы сказать вам, где находятся общие классы Java:


public static void getFullyQualifiedClassName(String className) {
        String[] commonPackages = {"java.lang", "java.util", "java.io", "java.math", "java.nio", "java.net"};
        String qualifiedName;
        for (String packageName : commonPackages) {
            try {
                Class.forName(packageName + "." + className).getName();
                System.out.println("A class with that name was found at: " + packageName);
            } catch (ClassNotFoundException e) {
                System.out.println("The class is not in package " + packageName);
            }
        }

Учитывая входное целое число, происходит следующий вывод:

A class with that name was found at: java.lang.Integer
The class is not in package java.util
The class is not in package java.io
The class is not in package java.math
The class is not in package java.nio
The class is not in package java.net

Это, вероятно, бесполезно, так как вам все равно нужно заранее знать возможные пакеты, но, возможно, это может указать вам правильное направление.

Другие вопросы по теме