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 Delimolis 解决方案的组合。该解决方案是完全动态的,无需使用任何条件。

此类通过传入属性名称来执行名称搜索;

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 回答