1

ここでは、インターフェイスを実装するPOJOクラスのセットがありますが、共通の属性はありません。別のメソッドからPOJOを動的に初期化する

public interface MainIfc {} 

class Ifc1 implements MainIfc { 
    private String a1; 
    public String getA1() { 
     return a1; 
    } 
    public void setA1(String a1) { 
     this.a1 = a1; 
    } 
} 

class Ifc2 implements MainIfc { 
    private String x1; 
    private String x2; 
    public String getX1() { 
     return x1; 
    } 
    public void setX1(String x1) { 
     this.x1 = x1; 
    } 
    public String getX2() { 
     return x2; 
    } 
    public void setX2(String x2) { 
     this.x2 = x2; 
    } 
} 

そして私は、私は別の値と値を実際のPOJOに基づいて返されるPOJOの種類を取得するために使用できる方法がいくつかあり、これらのPOJOクラスと組み合わせて使用​​します。

public class GetIfc { 
    public Class getIfcType(int code) { 
     if (code==1) 
      return Ifc1.class; 
     else 
      return Ifc2.class; 
    } 
    public MainIfc getIfc(int code) { 
     if (code==1) { 
      Ifc1 thisIfc = new Ifc1(); 
      thisIfc.setA1("Ifc1"); 
      return thisIfc; 
     } else { 
      Ifc2 thisIfc = new Ifc2(); 
      thisIfc.setX1("Ifc2"); 
      thisIfc.setX2("Ifc2"); 
      return thisIfc; 
     } 
    } 
} 

私のコードで具体的なPOJOを安全に読み取ってgetters/setterを使用する方法はありますか?私はReflectionに基づいて答えを出すが、それは私のために働いていないかなりの質問を行った。 getters/setterは表示されません。返されたオブジェクトのgetClass()私はそれがMainIfcインターフェイスであることを確認します。

解決しようとしている設計上の問題は、私が設計しようとしているREST APIオートメーションフレームワークに関係しています。基本的に私はClientResponseパーサを持っており、私が探しているPOJOを返信します。しかし、返されるPOJOのタイプについてテストケースを書いている人が心配することは望ましくありません。だから私は型とインスタンス化されたPOJOを返すことができると思っていたので、値を取得しましたが、これを動的に達成する方法には悩まされます。

+0

私はあなたが何をしようとしているのか不明です。私はBeanのような行動をしたいと思っていますが、間違いかもしれません。 – Fildor

+1

"返されたオブジェクトの.getClass()を呼び出すと、MainIfcインターフェイスになっています。"私はそれが信じがたいことがわかります。この動作を示すコードを少し追加してください。また、明確にしてください:あなたはそれを動作させる方法を探していますか、これを解決するために適切なオブジェクト指向の方法に興味がありますか? – Cephalopod

+0

すべての(public)フィールドを 'Field'オブジェクトのリストとして返すメソッドをクラスに追加することができます。おそらくMainIfcのメンバーです。しかし、私はこれがX-Y-Questionのように感じます。あなたが解決しようとしている問題は何ですか? – Fildor

答えて

0

MainIfcのコンシューマーは実際にPOJOを必要とするのか、それともその内部のデータだけですか?

MainIfcが消費者が必要とするデータを公開するメソッドを宣言すると、より洗練されたデザインになる場合があります。あなたのPOJOはMainIfcインターフェースが宣言するメソッドを実装することができます。また、POJOとは別のインターフェースを実装することを心配しないようにするために、インターフェースに適合するPOJOごとにラッパークラスを構築することもできます。

理想的には、インタフェースは、それを実装するすべてのクラスと対話するために使用できるいくつかのメソッドを公開し、基になるPOJO /実装について誰も知る必要はありません。

public interface MainIfc { 
    public Hash getAttributes(); 
    public setAttributes(Hash attributes); 
} 

class Ifc1 implements MainIfc { 
    private String a1; 
    public String getA1() { 
    return a1; 
    } 
    public void setA1(String a1) { 
    this.a1 = a1; 
    } 
    public Hash getAttributes() { 
    // return a hash with data that MainIfc consumer will need from this POJO 
    } 
    public setAttributes(Hash attributes) { 
    // copy hash attributes to corresponding POJO fields 
    } 
} 

class Ifc2 implements MainIfc { 
    private String x1; 
    private String x2; 
    public String getX1() { 
    return x1; 
    } 
    public void setX1(String x1) { 
    this.x1 = x1; 
    } 
    public String getX2() { 
    return x2; 
    } 
    public void setX2(String x2) { 
    this.x2 = x2; 
    } 
    public Hash getAttributes() { 
    // return a hash with data that MainIfc consumer will need from this POJO 
    } 
    public setAttributes(Hash attributes) { 
    // copy hash attributes to corresponding POJO fields 
    } 
} 
1

このコードを試してください。クラス内のすべてのメソッドだけでなく、Objectクラスから継承したメソッドも返されます。

public static void main(String[] args) throws ClassNotFoundException { 
     GetIfc getIfc=new GetIfc(); 
     MainIfc clas1s=getIfc.getIfc(1); 
     Class class1= clas1s.getClass(); 
     System.out.println(class1); 
     Method[] mem= class1.getMethods(); 
     for(Method mmm : mem) { 
      System.out.println(mmm.getName()); 
     } 
    } 
+0

私は直面している正確な要件と設計上の問題について私の質問を更新しました。お知らせ下さい。 – mbsingh

0

あなたはむしろ非論理的なことをしようとしているように私に聞こえます。戦略パターンや抽象ファクトリは、あなたの要件に適しているかもしれませんが、現時点では、達成しようとしていることを正確に理解していません。条件付きでキャストしたり、これらのクラスで異なるメソッドを呼び出すことは間違いありません。本当にこの道を歩み続けたいのであれば、私はオプションではないにしても、リフレクションをすることをお勧めします。柔軟性が必要な場合は、おそらくマップを使っています。

しかし、可能な限り私は間違いなくあなたのデザインを考え直すでしょう。

0

このコードを試してみてください。あなたの要件を完全に理解しているかどうかはわかりませんが、私の理解に基づいて、以下のコードはそのトリックを行うと思います。

public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, 
    IllegalArgumentException, InvocationTargetException { 
GetIfc getIfc = new GetIfc(); 
MainIfc clas1s = getIfc.getIfc(1); 
Field[] fields = clas1s.getClass().getDeclaredFields(); 
for (int i = 0; i < fields.length; i++) { 
    Field field = fields[i]; 
    Class fieldClasslasse = field.getType(); 

    if (field.getModifiers() == Modifier.PRIVATE) { 

    // you need to check fieldClass, if it is boolean then initials of the getter could be 'is' instead of 'get' 
    String methodNameGet = "get" + Character.toUpperCase(field.getName().charAt(0)) 
     + field.getName().substring(1); 
    String methodNameSet = "set" + Character.toUpperCase(field.getName().charAt(0)) 
     + field.getName().substring(1); 

    Method methodGet = clas1s.getClass().getDeclaredMethod(methodNameGet, null); 
    Object value = methodGet.invoke(clas1s, null); 
    if (value != null && value instanceof String) { 
     String valueUpper = ((String)value).toUpperCase(); 

     Class[] cArg = new Class[1]; 
     cArg[0] = String.class; 
     Method methodSet = clas1s.getClass().getDeclaredMethod(methodNameSet, cArg); 
     Object[] var = new Object[1]; 
     var[0] = valueUpper; 
     methodSet.invoke((Object) clas1s, var); 
    } 

    } 
} 

} 

上記のコードについて少し説明:オブジェクトのすべてのfiledsを取得し、私有財産であるかどうかを確認、はい、それは公共のゲッターとセッターを持っている必要があります場合は、Javaの規則に基づいて自分の名前を推測し、コールgetter、値を取得し、それがStringクラスのインスタンスであるかどうかをチェックし、そうであればUPPERCASEにして、setterを呼び出して新しい値を設定します。

関連する問題