Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create Fields and methods dynamically

Tags:

java

I want to add new fields(variables) and encapsulating methods for a given class. For example: A class name Student has no any fields like below:

public class Student implements Serializable{

}

then in my application an instance is created;

Student s=new Student();

I want to add new methods which do not exist for student class at the run time.for example: I want to add a field called studentName, and getStudentName() and setStudentName() methods.

Then at the run time the student object will be like this;

public class Student implements Serializable{

    private String studentName;

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

In my application objects are written to a text file and all objects of same type do not have all variables. Therefore, I want to add only the required fields to save memory.

Any way is there a way to do this? Any sample code or link?

EDIT: or else can we create a class either and create instances which does not exists ?

EDIT 2: Thanks all of you answered and got many info and ideas. And changed the way to a better path from your suggestions as well

like image 690
Débora Avatar asked Aug 16 '13 14:08

Débora


3 Answers

Instead of writing your own HashMap based solution you can use DynaBean and DynaClass: support not only simple properties but also indexed (Array) and mapped (Map).
DynaBean can be introspected to get properties and values so you can dump to file BUT with this solution you are only "simulating" a bean, your Student class doesn't really contains fields and accessors (you you call Student.getClass().getDeclaredField() you will get an empty array).

If you need to compose a "real" java java.lang.Class Javassist (my preferred choice, I used to resolve a solution similar to your question) or ASM (or CGLIB) are the best choiches.

like image 60
Luca Basso Ricci Avatar answered Nov 03 '22 05:11

Luca Basso Ricci


Why not just create a HashMap of values? Much more efficient, and has all the flexibility you're looking for.

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);
      }
}

Why a HashMap?

You said that all objects may have differing values, and you'll be defining those new methods and attributes by a String. Well.. this will achieve that functionality without any horrible bytecode manipulation. For example:

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

At the moment, you've only got the one value in your HashMap. The only overheard you have to face is the HashMap object itself, and two methods, which frankly is a fair trade off for a far tidier solution.

like image 45
christopher Avatar answered Nov 03 '22 06:11

christopher


You can use bytecode instrumentation libraries like Javassist or ASM for this purpose. Here is an example of adding a field or method by using Javassist.

like image 26
Santosh Avatar answered Nov 03 '22 06:11

Santosh