- Есть ли способ создать экземпляр класса по имени в Java?
- 8 ответов
- Метод 1 — только для классов, имеющих конструктор no-arg
- Метод 2
- Создание экземпляра класса по его имени и вызов конструктора
- Как создать объект класса по его строковому имени?
- Как создать класс по его имени java
- Как создать класс по его имени java
Есть ли способ создать экземпляр класса по имени в Java?
Я рассматривал вопрос: Создавать экземпляр класса из его имени строки, в котором описывается, как создать экземпляр класса при его имени. Есть ли способ сделать это на Java? У меня будет имя пакета и имя класса, и мне нужно будет создать объект с таким именем.
Ответ — да, но я думаю, вы должны спросить , хорошая ли это идея. С большой силой (рефлексией) приходит большая ответственность, и вы должны использовать ее, только если вы понимаете и учитываете последствия.
8 ответов
Метод 1 — только для классов, имеющих конструктор no-arg
Если у вашего класса нет конструктора no-arg, вы можете получить объект Class с помощью Class.forName() и использовать метод newInstance() для создания экземпляра (хотя будьте осторожны, что этот метод часто считается злым, потому что он может победить проверенные исключения Java).
Class clazz = Class.forName("java.util.Date"); Object date = clazz.newInstance();
Метод 2
Альтернативный более безопасный подход, который также работает, если класс не имеет никаких конструкторов no-arg, должен запросить ваш объект класса, чтобы получить его объект Constructor и вызвать метод newInstance() для этого объекта:
Class clazz = Class.forName("com.foo.MyClass"); Constructor constructor = clazz.getConstructor(String.class, Integer.class); Object instance = constructor.newInstance("stringparam", 42);
Оба метода известны как reflection. Вам, как правило, придется поймать различные исключения, которые могут произойти, включая такие вещи, как:
- JVM не может найти или не может загрузить ваш класс
- класс, который вы пытаетесь создать, не имеет подходящего типа конструкторов
- сам конструктор исключил исключение
- конструктор, который вы пытаетесь вызвать, не является общедоступным.
- был установлен диспетчер безопасности и предотвращает его отражение
Привет, как только мы создали объект из newInstance() , мы могли бы привести его обратно к нашему собственному объекту?
Я не понимаю этого. Я хочу получить доступ к классу в неизвестном файле в каком-то другом каталоге, у меня есть только имя пути / файла в виде строки. Строка «dir / unkonwn.java». Вызов Class.forName («dir / unknown») выдает мне ошибки.
MyClass myInstance = (MyClass) Class.forName("MyClass").newInstance();
Стоит отметить, что это не работает, если у класса нет конструктора без параметров (и есть другие конструкторы) или если конструктор без параметров недоступен.
используйте Class.forName( «String name of class» ). newInstance();
Это приведет к инициализации класса с именем A.
Чтобы упростить получение полного имени класса для создания экземпляра с помощью Class.forName(. ) , можно использовать метод Class.getName() . Что-то вроде:
class ObjectMaker < // Constructor, fields, initialization, etc. public Object makeObject(Classclazz) < Object o = null; try < o = Class.forName(clazz.getName()).newInstance(); >catch (ClassNotFoundException e) < // There may be other exceptions to throw here, // but I'm writing this from memory. e.printStackTrace(); >return o; > >
Затем вы можете отбросить объект, который вы возвращаете, в любой класс, который вы передаете, в makeObject(. ) :
Data d = (Data) objectMaker.makeObject(Data.class);
Class class1 = Class.forName(ClassName); Object object1 = class1.newInstance();
Использовать отражение java
Создание новых объектов Не существует эквивалента вызова метода для конструкторов, потому что вызов конструктора эквивалентен созданию нового объекта (чтобы быть точнее, создание нового объекта связано как с распределением памяти, так и с построением объекта). Поэтому ближайший эквивалент предыдущего примера — сказать:
import java.lang.reflect.*; public class constructor2 < public constructor2() < >public constructor2(int a, int b) < System.out.println( "a = " + a + " b = " + b); >public static void main(String args[]) < try < Class cls = Class.forName("constructor2"); Class partypes[] = new Class[2]; partypes[0] = Integer.TYPE; partypes[1] = Integer.TYPE; Constructor ct = cls.getConstructor(partypes); Object arglist[] = new Object[2]; arglist[0] = new Integer(37); arglist[1] = new Integer(47); Object retobj = ct.newInstance(arglist); >catch (Throwable e) < System.err.println(e); >> >
который находит конструктор, который обрабатывает указанные типы параметров и вызывает его, для создания нового экземпляра объекта. Значение этого подхода заключается в том, что оно чисто динамическое, с поиском конструктора и вызовом во время выполнения, а не во время компиляции.
Создание экземпляра класса по его имени и вызов конструктора
Существует задача, с которой может столкнуться любой разработчик на Java: необходимо создать экземпляр класса, зная только его имя, и передать параметры в его конструктор. Это может быть полезно, когда имя класса или параметры конструктора зависят от пользовательского ввода или внешних условий.
В качестве примера, представим следующую ситуацию:
// имя класса и параметр конструктора получены из внешнего источника String className = "com.example.MyClass"; String param = "test";
Теперь нужно создать экземпляр класса MyClass из пакета com.example , используя конструктор, который принимает строку в качестве параметра.
В Java для этого можно использовать рефлексию. Рефлексия позволяет работать с классами и их членами (методами, полями, конструкторами) динамически, во время выполнения программы.
Вот как это можно сделать:
// загрузка класса по имени Class<?> cls = Class.forName(className); // получение конструктора, который принимает строку Constructor<?> constructor = cls.getConstructor(String.class); // создание экземпляра класса с помощью конструктора Object obj = constructor.newInstance(param);
В этом коде сначала загружается класс по имени с помощью метода Class.forName() . Затем получается конструктор этого класса, который принимает строку, с помощью метода getConstructor() . Наконец, создается экземпляр класса с помощью этого конструктора, вызывая метод newInstance() .
Обратите внимание, что при работе с рефлексией могут возникнуть исключения, такие как ClassNotFoundException , NoSuchMethodException и InstantiationException , которые следует обрабатывать.
Таким образом, в Java есть возможность создать экземпляр класса по его имени и передать параметры в его конструктор. Это может быть полезно во многих ситуациях, когда имя класса или параметры конструктора не известны заранее.
Как создать объект класса по его строковому имени?
Знатоки, подскажите, как можно создать объект класса, если есть его имя в качестве строки? В задаче получаем String key = «user» (например). Есть класс User. Я хочу создать его объект.
public static void main(String[] args) throws Exception BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); Person person = null; String key; //тут цикл по чтению ключей, пункт 1 while ((key = reader.readLine()).equals("user") || key.equals("loser") || key.equals("coder") || key.equals("proger")) //создаем объект, пункт 2 //Это моя попытка создать объект класса с помощью его имени в строковом виде //Делаю первую букву полученного ключа заглавной /* String className = key.substring(0, 1).toUpperCase() + key.substring(1); // А вот тут как правильно создать объект? person = (Person) Class.forName(className).newInstance();*/ //создаем объект, пункт 2 - это решение прошло проверку switch (key) case "user": person = new Person.User(); break; case "loser": person = new Person.Loser(); break; case "coder": person = new Person.Coder(); break; case "proger": person = new Person.Proger(); break; default: break; > doWork(person); //вызываем doWork > >
Как создать класс по его имени java
Боже, хоть одна всеняемая статья про Рефлекшн для новичков. А то, другие авторы сразу выввливают кучу методов, без объяснений для нубов. Спасибо, автор!
Грамотно написанный класс в Java: — У меня всё как надо, всё что нужно скрыть, помечено Private, я вообще не вызываю багов вовремя работы программы. 💪😎👍 Reflection API: — 😂 Я вас умоляю, не смешите мои подковы методы).
На собеседовании : — Reflection API, для чего он нужен? — Он позволяет наиболее циничный способом попрать принцип инкапсуляции в java.
Вызов метода мяу обычным способом : Кот, мяукни! Вызов метода мяу через рефлексию : Мяу, прозвучи от того кота!
clazz = Class.forName(Cat.class.getName());
Вместо того, чтобы сразу получить объект класса, мы сначала получаем имя класса (которое нам известно), а потом по нему получаем объект класса. Или это как-то связано с полным именем (learn.javarush.Cat) ?
Я статью только начал читать, но уже появился вопрос, причём, видимо, элементарный: если класс Cat наследует класс Animal, то зачем в наследнике повторять те же поля private String name; private int age; Они же ему переходят по наследству? Вопрос второй: как понять эти строки Class clazz = Class.forName(className); Cat cat = (Cat) clazz.newInstance(); Если стоит задача создать объект класса, чьё имя на момент компиляции неизвестно, то откуда в тексте программы это самое неизвестное имя? Я бы мог представить такую строку: Object obj = clazz.newInstance(); Она была бы универсальной для любого типа. И она есть в этом же коде ниже, в методе createObject(), но он же не вызывается вроде. Вызывается createCat()
вернулся сюда из 34 уровня лекции 8 задачи 2, запомните как создать обж с конструктором который принимает аргумент.
На этом наша лекция подошла к концу! Она получилась довольно большой, но сегодня ты узнал много нового :)
И сегодня, и вчера, и позавчера. Смог прожевать только за три вечера. Не уверен, что прожевал тщательно, и не случится изжоги. 🤣
Как создать класс по его имени java
Боже, хоть одна всеняемая статья про Рефлекшн для новичков. А то, другие авторы сразу выввливают кучу методов, без объяснений для нубов. Спасибо, автор!
Грамотно написанный класс в Java: — У меня всё как надо, всё что нужно скрыть, помечено Private, я вообще не вызываю багов вовремя работы программы. 💪😎👍 Reflection API: — 😂 Я вас умоляю, не смешите мои подковы методы).
На собеседовании : — Reflection API, для чего он нужен? — Он позволяет наиболее циничный способом попрать принцип инкапсуляции в java.
Вызов метода мяу обычным способом : Кот, мяукни! Вызов метода мяу через рефлексию : Мяу, прозвучи от того кота!
clazz = Class.forName(Cat.class.getName());
Вместо того, чтобы сразу получить объект класса, мы сначала получаем имя класса (которое нам известно), а потом по нему получаем объект класса. Или это как-то связано с полным именем (learn.javarush.Cat) ?
Я статью только начал читать, но уже появился вопрос, причём, видимо, элементарный: если класс Cat наследует класс Animal, то зачем в наследнике повторять те же поля private String name; private int age; Они же ему переходят по наследству? Вопрос второй: как понять эти строки Class clazz = Class.forName(className); Cat cat = (Cat) clazz.newInstance(); Если стоит задача создать объект класса, чьё имя на момент компиляции неизвестно, то откуда в тексте программы это самое неизвестное имя? Я бы мог представить такую строку: Object obj = clazz.newInstance(); Она была бы универсальной для любого типа. И она есть в этом же коде ниже, в методе createObject(), но он же не вызывается вроде. Вызывается createCat()
вернулся сюда из 34 уровня лекции 8 задачи 2, запомните как создать обж с конструктором который принимает аргумент.
На этом наша лекция подошла к концу! Она получилась довольно большой, но сегодня ты узнал много нового :)
И сегодня, и вчера, и позавчера. Смог прожевать только за три вечера. Не уверен, что прожевал тщательно, и не случится изжоги. 🤣