2013-08-16 5 views
3

Я хочу добавить новые поля (переменные) и методы инкапсуляции для данного класса. Например: Имя класса Student не имеет полей, как показано ниже:Динамически создавать поля и методы

public class Student implements Serializable{ 

} 

то в моем приложении создается экземпляр;

Student s=new Student(); 

Я хочу, чтобы добавить новые методы, которые не существуют для класса студентов на беге time.for Например: Я хочу добавить поле под названием studentName и getStudentName() и setStudentName() методы.

Тогда во время выполнения объект-ученик будет таким:

public class Student implements Serializable{ 

    private String studentName; 

    public void setStudentName(..){} 
    public String getStudentName(){return ...;} 
} 

В моих объектах приложения записываются в текстовый файл, и все объекты того же типа не имеют всех переменных. Поэтому я хочу добавить только необходимые поля для сохранения памяти.

Любой способ - это сделать это? Любой пример кода или ссылки?

EDIT: или же мы можем создать класс и создать экземпляры, которые не существуют?

EDIT 2: Спасибо, что все вы ответили и получили много информации и идей. И изменил путь к лучшему пути от ваших предложений, а также

+2

Частичный дубликат: http://stackoverflow.com/questions/6680674/can-a-java-class-add-a-method-to-itself-at-runtime – christopher

+4

Похоже, вы можете придумать решение проблемы необоснованно, и тот, который может быть лучше рассмотрен с более продуманным представлением о модели данных (и, возможно, больше типов). –

+0

Не следуй за этой дорогой, ради бога! –

ответ

5

Почему бы не просто создать значения HashMap? Гораздо эффективнее, и у вас есть все гибкость, которую вы ищете.

public class Student 
{ 
     private HashMap<String, String> values; 

     public Student() 
     { 
      this.values = new HashMap<String, String>(); 
     } 

     public void addValue(String name, String value) 
     { 
      values.put(name, value); 
     } 

     public String getValue(String name) 
     { 
      return values.get(name); 
     } 
} 

Почему HashMap?

Вы сказали, что все объекты могут иметь разные значения, и вы будете определять эти новые методы и атрибуты с помощью String. Ну .. это позволит достичь этой функциональности без каких-либо ужасных манипуляций с байт-кодами. Например:

String attrName = "name"; 
String attrValue = "jim"; 
Student stu = new Student(); 
stu.addValue(attrName, attrValue); 

На данный момент, вы получили только одно значение в вашей HashMap. Единственный подслушатель, с которым вы столкнулись, это сам объект HashMap и два метода, которые, откровенно говоря, являются честным компромиссом для более удобного решения.

+0

Я думаю, что OP лучше переосмыслить модель данных, как предложил Jon Skeet в своих комментариях, а не создавать какой-то класс, который может содержать любой произвольный набор атрибутов. – GriffeyDog

+0

Не беспокойтесь о потреблении памяти в HashMap, возможно, вы хотите дать ему первоначальную оценку мощности при строительстве. –

+0

Я думаю, что эти детали больше подходят для работы OP. Мне не нравится раздавать им все. И согласился Гриффи, но если мы сможем достичь желаемой функциональности, тогда имеет смысл опубликовать его. Если что-нибудь, поэтому будущие читатели знают, что делать, этот тип класса * является правильным выбором. – christopher

0

Практически говоря, не на Java. На других языках, таких как Javascript, это возможно.

+0

Отражение не может добавлять поля. Для этого вам нужна обработка байт-кода. – Kayaman

+2

Вы можете сделать это с помощью библиотек инструментов для подписи, таких как ASM или Javassist. – Santosh

+0

@ Сантош, конечно. – Brad

0

Я не верю, что это возможно в java, но я уверен, что это добавит только в память, потому что если вы добавляете их динамически, они должны быть предварительно настроены + код, чтобы добавить их динамически.

1

Хотя это возможно при манипулировании байт-кодами, и это было бы неразумно, особенно если вы намереваетесь сделать это, чтобы «сохранить память». Маловероятно, что у вас будет так много данных, что это будет иметь значение, и если бы вы это сделали, вы бы сохранили их в базе данных в любом случае.

3

Для этой цели вы можете использовать библиотеки инструментов для байт-кода, например Javassist или ASM. Here is an example добавления поля или метода с помощью Javassist.

+0

Правда, но я не думаю, что это хорошая идея, чтобы следовать этому маршруту специально для тех, кто в первую очередь задает такой основной вопрос о Java. –

+0

Да. Согласен. Это был еще один вариант. – Santosh

0

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

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

Однако это решение не будет сохранять память, если максимальное количество атрибутов довольно велико, и у большинства объектов есть значения для небольшого числа таких атрибутов.

public class Entity { 

     // 5 is an estimate for the number attrs. 
     private Map<String,?> attrs = new HashMap<>(5); 

     public Object getAttribute(String name) { return attrs.get(name); } 

     public void setAttribute(String name, Object obj) { attrs.put(name,obj); } 

    } 

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

0

Вместо того чтобы писать собственное решение на основе HashMap, вы можете использовать DynaBean and DynaClass: поддержка не только простых свойств, но и индексации (массива) и сопоставления (Карта).
DynaBean можно интроспектирован получить свойства и значения, так что вы можете сбросить в файл НО с этим решением, вы только «имитирующей» боб, ваш Student класс действительно не содержит поля и аксессоров (вы вы звоните Student.getClass().getDeclaredField() вас получит пустой массив).

Если вам нужно составить «настоящую» java java.lang.Class Javassist (мой предпочтительный вариант, я использовал для решения решения, аналогичного вашему вопросу), или ASM (или CGLIB) - лучшие выборки.

+0

Это 'HashMap', а не' HasMap' небольшая опечатка там –

Смежные вопросы