3

メソッドを動的に呼び出す方法を理解しようとしています。メソッド名を説明する文字列がありますが、その方法がわかりません。これはリフレクションでできると思っていましたが、成功していません。例

set.add(vehicleConfiguration.getVehicleYear.getName());

set.add(vehicleConfiguration.getVehicleMake().getName());

set.add(vehicleConfiguration.getVehicleModel().getName());

getVehicleYear などを除いて、すべてのメソッド呼び出しが同じであることがわかります。

メソッド名を説明する文字列がありますが、使い方がわかりません。

反省してここまでたどり着きましたが失敗しました。

set.add(Class.forName("VehicleConfiguration").getMethod("vehicleMake", null).getName());

前もって感謝します。

4

4 に答える 4

4

お探しのクラスは ですMethod。適切な javadoc を注意深く読んでください。

たとえば、メソッドを取得できます

// assumign `getVehicleMake` is the name of the method and it accepts no parameters
Method method = VehicleConfiguration.class.getMethod("getVehicleMake"); 
// VehicleConfiguration.class can be replaced by
// Class.forName("VehicleConfiguration") 
// if VehicleConfiguration is the fully qualified, ie. with packages, name of the class
// other you need Class.forName("com.yourpackage.VehicleConfiguration")

invoke()次に、クラスのインスタンスでこのメソッドを実行する必要があります。

VehicleConfiguration instance = new VehicleConfiguration();

Object returnObject = method.invoke(instance); // assuming no parameters

次に を呼び出すgetName()には、返されたオブジェクトをメソッドを持つ型にキャストする必要があります。getMake()がタイプのメソッドであると仮定すると、次のVehicleMakeように呼び出します

((VehicleMake)returnObject).getMake();
于 2013-09-07T19:30:09.043 に答える
2

getVehicleMakeではなく、実際のメソッド名を使用する必要がありvehicleMakeます。

さらに、これをエクササイズ以外の目的で使用している場合は、自分で巻かないでください。CommonsBeanUtilsまたは Spring のを使用しBeanWrapperます。

于 2013-09-07T19:28:38.287 に答える
1

私のコメントを拡張すると、あなたが示したすべてのメソッドにはメソッドがあるので、getName()これを定義する単純なクラスを作成しましょう:

class Nameable
{
    private String name;

    public Nameable(final String name)
    {
        this.name = name;
    }

    public String getName()
    {
        return this.name;
    }
}

Make、Model、Year のオブジェクトを作成すると、これらはすべてこのクラスを使用できるため、交換可能に使用でき、次のように組み合わせることができますCar

class Car
{
    public final Nameable make;
    public final Nameable model;
    public final Nameable year;

    public Car(Nameable make, Nameable model, Nameable year)
    {
        this.make = make;
        this.model = model;
        this.year = year;
    }

    public Nameable getInfo(final String info)
    {
        switch(info)
        {
            case "make": return this.make;
            case "model": return this.model;
            case "year": return this.year;
        }
        return null;
    }
}

次に、簡単な実装は次のようになります。

class PaganiZonda2006 extends Car
{
    public PaganiZonda2006()
    {
        super(new Nameable("Pagani"), new Nameable("Zonda"), new Nameable("2006"));
    }
}

最後に、情報を取り出したい場合は、次のように読むことができます。

public static void main(String[] args)
{
    Car car = new PaganiZonda2006();
    System.out.println(car.getInfo("make").getName()); //Pagani
    System.out.println(car.getInfo("model").getName()); //Zonda
    System.out.println(car.getInfo("year").getName()); //2006
}
于 2013-09-07T19:52:33.420 に答える
0

これが、MrLore ソリューションと Sotirios Delimanolis ソリューションの組み合わせである私の最終的なソリューションになりました。このソリューションは、条件を使用せずに完全に動的です。

このクラスは、プロパティ名を渡すことによって名前の検索を実行します。

String propertyName = "vehicleYear";

vehicleConfiguration.getInfo(propertyName).getName()

propertyName = "vehicleMake";

vehicleConfiguration.getInfo(propertyName).getName()

このクラスは VehicleConfiguration を表します

@Entity
public class VehicleConfiguration extends StatefulEntity {

    @ManyToOne
    @JoinColumn(name = "year_id")
    private VehicleYear vehicleYear;

    @ManyToOne
    @JoinColumn(name = "make_id")
    private VehicleMake vehicleMake;

    public LookupBaseEntity getInfo(final String fieldName) {
        try { 
            String methodName = WordUtils.capitalize(fieldName);
            Method method = VehicleConfiguration.class.getMethod("get" + methodName);  
            return (LookupBaseEntity) method.invoke(this); 
        } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
            Logger.getLogger(VehicleConfiguration.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
}

このクラスは VehicleYear を表します

@Entity
public class VehicleYear extends LookupBaseEntity {

}

このクラスは VehicleMake を表します

@Entity
public class VehicleMake extends LookupBaseEntity {

}

どちらも LookupBaseEntity を拡張します

public class LookupBaseEntity extends StatefulEntity {

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}
于 2013-09-07T22:38:37.670 に答える