我正在试图弄清楚如何动态调用方法。我有一个描述方法名称的字符串,但我不知道该怎么做。我认为这可以通过反思完成,但没有取得任何成功。实施例
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());
提前致谢。
答案 0 :(得分: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();
答案 1 :(得分:2)
您必须使用实际方法名称:getVehicleMake
,而不是vehicleMake
。
此外,如果您将此作为练习以外的任何其他内容使用,请不要自己动手。使用Commons BeanUtils
或Spring BeanWrapper
。
答案 2 :(得分: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
}
答案 3 :(得分: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;
}
}