В Java программе необходимо создать объект, но заранее не известно сколько и какие поля будут участвовать в конструкторе. Есть ли возможность во время выполнения добавлять к классу конструктор с необходимым набором параметров?
Есть следующие классические пути.
В качестве примера используем такой максимальный конструктор
public Person(String name, Int age, Double weight)
Если вариантов использования конструктора ограниченное количество (т.е., например, всего три варианта: name+age,+weight, name+age, name+weight), то правильным путем будет создание трех конструкторов:
public Person(String name, Int age, Double weight){код}
public Person(String name, Int age){
this(name, age, 25.4);
}
public Person(String name, Double weight){
this(name, 78, weight);
}
Если прямо совсем неопределенное количество аргументов одного класса, то имеет смысл либо передавать их коллекцию:
public MyNumbers(List<Int> numbers){код}
Либо использовать конструкцию VARARGS:
public MyNumbers(Int... numbers){код}
В принципе никто не мешает передавать List<Object>
, но это если совсем безнадёга - так делать не надо.
Если аргументы заранее известны, их много, но неизвестно, какие будут заданы, то стоит использовать шаблон проектирования Builder
Если совсем упрощенно, то:
class PersonBuilder{
private String name = "";
private Int age = 78;
private Double weight = 25.4;
public PersonBuilder setName(String name){
this.name = name;
return this;
}
// для двух других параметров аналогично
public Person build(){
return new Person(name, age, weight);
}
}
Person person = (PersonBuilder()).setName("John").setWeight(22.7).build();
Нет. В Java методы, к сожалению для многих, методы не являются обьектами, поэтому их нельзя произвольно вставлять/удалять/переделывать во времени выполнения.
Наиболее близким к вашей задаче альтернативным решением является реализация рефлексивного конструктора, принимающего два массива: один с названиями полей, другой - с соотвествующими значениями для инициализации.
...
public SomeClass (String[] fields, Object[] valuesForInit) {
//Получаем класс и поля
Class clazz = SomeClass.class;
Field[] classFields = clazz.getFields();
//Перебираем список всех полей и список нужных для инициализации
for (int i = 0; i < fields.length(); i++) {
for (Field classField : classFields) {
//Если поле нужно инициализировать и значение соответствует типу поля...
if (field[i] == classField.getName() && valuesForInit[i] instanceof classField.getType()) {
//...инициализируем как нужно
//Тут вы как-нибудь сами
}
}
}
}
...
Однако учтите - обычная рефлексия ужасно бьет по производительности. Если для вас это критично, ищите способы ускорения (например) или другие решения.
Есть такой способ хакинга (заранее предупреждаю, что это антипаттерн):
Еще раз - так не рекомендуется делать, но иногда так делается. Сам лично когда то делал такую поделушку.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Есть Map<String, Object> с полями объектаНужно конвертировать эту мапу в объект так как это сделал бы Hibernate, используя колонки @Column(name="
Есть такой вот код, в условиях задачи сказано: Display the average and total rating of all student
Вообще никак нельзя определить, что приложение декомпилируетсяДекомпилятор работает с кодом как с потоком байтов, а не исполняемой сущностью