Java classes with dynamic fields

I'm looking for smart ways to create dynamic Java classes, which are classes where you can add / remove fields at runtime. Usage scenario: I have an editor in which users should be able to add fields to the model at runtime, or perhaps even create an entire model at runtime.

Some development goals:

  • Enter safe without actuation, if possible, for custom code that works with dynamic fields (this code will come from plugins that extend the model in unexpected ways).
  • Good performance (can you beat HashMap ? Maybe use an array and assign indexes to fields during installation?)
  • The "reuse" field (i.e. if you use the same field in several places, it should be defined once, and then reused).
  • Computed fields that depend on the value of other fields
  • Signals should be sent when fields change value (optional via Beans API)
  • "Automatic" parental relationship with parents (when adding a child to the parent, the parent pointer in the child must be set to "free").
  • Easy to understand
  • Ease of use

Please note that this is a “outside the circle” question. I will give an example below, so that you are in the mood :-)

+6
java dynamic field
source share
5 answers

The obvious answer is to use a HashMap (or a LinkedHashMap if you care about the order of the fields). Then you can add dynamic fields using the get(String name) and set(String name, Object value) methods.

This code can be implemented in a common base class. Since there are only a few methods, it is also easy to use delegation if you need to extend something else.

To avoid casting problems, you can use a type-safe map of objects :

  TypedMap map = new TypedMap(); String expected = "Hallo"; map.set( KEY1, expected ); String value = map.get( KEY1 ); // Look Ma, no cast! assertEquals( expected, value ); List<String> list = new ArrayList<String> (); map.set( KEY2, list ); List<String> valueList = map.get( KEY2 ); // Even with generics assertEquals( list, valueList ); 

The trick here is the key that contains the type information:

 TypedMapKey<String> KEY1 = new TypedMapKey<String>( "key1" ); TypedMapKey<List<String>> KEY2 = new TypedMapKey<List<String>>( "key2" ); 

Performance will be fine.

Reuse of fields is carried out using the same type of values ​​or by expanding the class of keys of the map such as safe objects with additional functionality.

The calculated fields can be implemented with a second map, which stores Future instances that perform the calculation.

Since all manipulations occur in only two (or at least several) methods, the starting signals are simple and can be done in any way.

To implement automatic processing of a parent / child element, set the signal listener to the "set parent" signal of the child element, and then add it to the new parent element (and remove it from the old one, if necessary).

Since no framework is used and no tricks are required, the resulting code should be fairly clean and understandable. Not using String as keys has the added benefit that people will not litter code with string literals.

+2
source share

Enter safe without casting, if possible, for custom code that works in dynamic fields (this code will come from plugins that extend the model in unexpected ways)

AFAIK, this is not possible. You can only get type safety without type casting if you use static typing. Static typing refers to method signatures (in classes or interfaces) that are known at compile time.

The best you can do is to have an interface with a bunch of methods like String getStringValue(String field) , int getIntValue(String field) , etc. And of course, you can only do this for a specific set of types. Any field whose type is not in this set will need a type.

+2
source share

So basically you are trying to create a new type of object model with more dynamic properties, a bit like a dynamic language?

It might be worth looking at the source code of Rhino (i.e., Javascript implemented in Java), which faces a similar task of implementing a dynamic type system in Java.

On top of my head, I suspect you will find that internal HashMaps will ultimately work best for your purposes.

I wrote a small game ( Tyrant Affordable Source - GPL ) using a similar model of dynamic objects with a HashMaps image, it worked fine and performance was not a problem. I used a few tricks in the get and set methods to enable dynamic property modifiers, I'm sure you could do the same to implement your signals and parent / parent relationships, etc.

[EDIT] See the source of BaseObject , how it is implemented.

+1
source share

You can use the bytecode manipulation libraries for this. The disadvantage of this approach is that you need to create your own class loader to dynamically change changes to classes.

+1
source share

I am doing almost the same thing, this is a pure Java solution:

  • Users generate their own models, which are stored as a JAXB schema.
  • The scheme is compiled in Java classes on the fly and stored in user banks
  • All classes are forced to extend one “root” class, where you can add any additional functionality.
  • Corresponding class loaders are implemented using the "model change" listeners.

Speaking of performance (which is important in my case), you can hardly defeat this solution. Reuse of the same XML document.

+1
source share

All Articles