I want to create a tools that automatically initialized field of a class with default constructor of object (it should exists). For simple variable and also for multi-dimensional tables.
I just have prototype it and it seems to work.
In the this short sample I use annotation to specify table sizes :
@sizes( { 3, 4 } )
public MyClass table[][];
@sizes( {} )
public MyClass val;
I have do this using reflection to find fields (not exposed in following sample) and also to initialize fields.
Do you think it's possible to have other possible solution to code the method generateZeroValue( Class<?> klass, int [] sizes )
public class InitializeFields
{
@Retention(RetentionPolicy.RUNTIME)
static @interface sizes {
int [] value();
}
static class MyClass {
static int cpt = 0;
int value;
public MyClass() {
cpt += 1;
value = cpt;
}
}
@sizes( { 3, 4 } )
public MyClass table[][];
@sizes( {} )
public MyClass val;
static void initializeAll( Object obj ) throws Exception {
// real code uses introspection to call initialize method on all field with annotation
Field f = InitializeFields.class.getField("table");
sizes a = f.getAnnotation(sizes.class);
initialize( obj, f, a.value() );
Field f2 = InitializeFields.class.getField("val");
sizes a2 = f2.getAnnotation(sizes.class);
initialize( obj, f2, a2.value() );
}
static void initialize( Object obj, Field f, int [] sizes) throws Exception {
f.set(obj, generateZeroValue( f.getType(), sizes));
}
static Object generateZeroValue( Class<?> klass, int [] sizes) throws Exception {
int dims = sizes.length;
Class< ? > componentType = klass;
for( int i = 0; i<sizes.length; i++)
componentType = componentType.getComponentType();
Constructor< ? > constructor = componentType.getConstructor();
Supplier<Object> myConstructor = () -> {
try {
return constructor.newInstance();
} catch (Exception e) {
return null;
}
};
if (dims > 0) {
Object result = Array.newInstance( componentType, sizes );
initializeSubTables( (Object[]) result , dims, myConstructor );
return result;
} else {
return myConstructor.get();
}
}
static void initializeSubTables( Object[] table, int dims, Supplier<Object> safeConstructor) throws Exception
{
if (dims > 1)
for (int i=0; i<table.length; i++)
initializeSubTables( (Object[]) table[i], dims-1, safeConstructor);
else
for (int i=0; i<table.length; i++)
table[i] = safeConstructor.get();
}
public static void main(String[] args) throws Exception
{
InitializeFields ep = new InitializeFields();
initializeAll(ep);
}
}
Aucun commentaire:
Enregistrer un commentaire