Java reflection - enum generate -


i make program can generate source code of class,enum , interfaces using reflection have problem enum generating.

my eumtest class

public enum enumtest{ a,b;  private  string r;  private enumtest(){  }  private void some(){  }  public int[] some2(int[] b){     return b; } } 

method generate enum file

private void generateenum(class<?> cls,printwriter writer) {     this.writepackage(cls, writer);     this.writeannotations(writer, cls.getdeclaredannotations());     writer.write(modifier.tostring(cls.getmodifiers())+ " enum " + cls.getsimplename());     this.writeimplementation(cls, writer);     writer.write("{");     this.writenewline(writer);     object[] cons = cls.getenumconstants();     (int = 0; < cons.length; i++) {         writer.write(cons[i].tostring());         if(i != cons.length - 1)             writer.write(",");     }     writer.write(";");     this.writenewline(writer);     this.writefields(cls, writer);     this.writeconstructors(cls, writer);     this.writemethods(cls,writer);     writer.write("}"); } 

result new enum

package metaprogramovanie.test; public final enum enumtest{ a,b; private java.lang.string r; private static final metaprogramovanie.test.enumtest[] $values;  private enumtest(java.lang.string arg0,int arg1){ } public static metaprogramovanie.test.enumtest[] values(){ return null; } public static metaprogramovanie.test.enumtest valueof(java.lang.string arg0){ return null; } private void some(){  } public int daco(int arg0){ return 0; }  } 

as can see there som errors. example modifier generate final , enum cant final, next there more methods , fields, constructor has paramaters ...

constructor generate

private void writeconstructors(class<?> cls, printwriter writer){     constructor[] cons = cls.getdeclaredconstructors();     (constructor constructor : cons) {         this.writeannotations(writer, constructor.getdeclaredannotations());         writer.write(modifier.tostring(constructor.getmodifiers()) + " " + cls.getsimplename());         this.writeparameters(writer,constructor.getparameters());         writer.write("{");         this.writenewline(writer);         writer.write("}");         this.writenewline(writer);     } } 

field generate

private void writefields(class<?> cls, printwriter writer){     field[] atr = cls.getdeclaredfields();     (field field : atr) {         if(field.isenumconstant()){             system.out.println("je");         }         else{             this.writeannotations(writer, field.getdeclaredannotations());             writer.write(modifier.tostring(field.getmodifiers())+" " + field.gettype().gettypename()+ " " + field.getname());             if(modifier.isstatic(field.getmodifiers())){                 try{                     object value = field.get(null);                     writer.write(" = " + this.getfieldvalue(field));                 }catch(illegalaccessexception ex){                  }             }             writer.write(";");             this.writenewline(writer);         }     }     this.writenewline(writer); } 

methods generate

 private void writemethods(class<?> cls, printwriter writer){     method[] methods = cls.getdeclaredmethods();     (method met : methods) {         this.writeannotations(writer, met.getdeclaredannotations());         writer.write(modifier.tostring(met.getmodifiers())+" "+met.getreturntype().gettypename() +" "+ met.getname());         this.writeparameters(writer, met.getparameters());         writer.write("{");         this.writenewline(writer);         if(!met.getreturntype().equals(void.type)){             this.writemethodbody(writer,met);         }         this.writenewline(writer);                writer.write("}");         this.writenewline(writer);     }     this.writenewline(writer); } 

if have ideas how enum can compiled.

here explanation of why stuff.

enums implemented using lot of code synthesized compiler, "behind scenes" behave java language spec specifies, without requiring jvm drastically changed.

the java language specification says, example, that:

  • an enum implicitly final unless there's constant body.
  • any enum implicitly declares methods values() , valueof(string).

for reason, got final modifier enumtest, , got 2 methods.

in addition, compiler synthesizes code implement of required stuff efficiently. example, source of array copied , returned method values() placed in synthetic field named, in case, $values. filled @ initialization of enum, , can copied whenever values() called.

also, initialize constants, compiler adds 2 hidden parameters each of constructors. if have empty constructor, behind scenes has 2 parameters - constant's name , ordinal number. if have constructor 1 parameter, behind scenes have 3 parameters.

there additional synthetic code created when have constants own bodies.

all of these latter implementations done compiler not documented in jls , left compiler decide how implement. long enum behaves correctly result of whatever code compiler generates, free generate in way chooses.


tips overcoming of problems have encountered:

  • instead of using modifier.tostring(cls.getmodifiers()) print enum modifiers, use

    modifier.tostring(cls.getmodifiers() & ~ modifier.final & ~ modifier.abstract) 

    this excludes final modifier output abstract modifier show if add abstract methods enum (and process constant bodies, haven't done far).

  • use field.issynthetic() method check whether field synthesized compiler, , not output fields method returns true. rid of $values field.
  • the 2 methods values() , valueof(string) not considered synthetic , if use method.issynthetic() on them, return false. you'll have check each method find in enum. if 1 of these 2 methods, signature , return type specified in jls, skip them , not output them.

the tricky part getting rid of 2 additional parameters of each of constructors. basically, when iterate through constructor parameters, can skip first 2 parameters. however, remember work code generated oracle compiler , not guaranteed in future versions or other compiler!


Comments

Popular posts from this blog

c# - Validate object ID from GET to POST -

node.js - Custom Model Validator SailsJS -

php - Find a regex to take part of Email -