【问题标题】:How to find a field of an object using a Generic method?如何使用通用方法查找对象的字段?
【发布时间】:2018-08-07 19:12:04
【问题描述】:

我有一个带有公共“x”字段的 Cube 对象。我的 Cube 类中有一个 toString 方法,它打印出 x、y、z 字段,但是当我直接访问它时,出现错误:字段无法解析或不是字段

public <T> void setPosition(T object){
   System.out.println(object);  
   System.out.println(object.x); // error here
}

【问题讨论】:

  • T 可以是任何 Object,因此编译器不知道 x 是否是它的一个字段。如果 T 被声明为扩展某些类型(例如 public &lt;T extends Point&gt; ...),并且该类型具有 x,那么这将起作用。
  • ^ 那 - 换句话说 - 如果你知道你可以期待什么类型,使用 X instanceof Y 来检查它是否是你所期望的然后转换它。
  • 嗯,但是说我有多个类都具有相同的字段,所以我知道该字段将在那里(x,y,z),所以不应该有办法能够有一个适用于具有相似字段的多个类的通用方法吗?
  • 是的,如果所有这些对象都有一个父对象或实现一个也声明该字段/方法的接口。或者正如 Worthless 所写,使用 instanceof 和强制转换。
  • 是父母这样做的一个很好的例子吗?

标签: java generics field


【解决方案1】:

我建议定义一个接口来声明您的多种不同类型将公开的方法。比如:

public interface ValueProducer {
  public String getValue();
}

然后,您的 Cube 类型将如下所示:

public <T extends ValueProducer> void setPosition (T obj) {
   System.out.println(obj);  
   System.out.println(obj.getValue());
}

然后,您希望使用此方法的任何类型只需要实现接口ValueProducer,并且仍然可以扩展或实现适合其用例的任何其他类型。

或者,您可以完全省略泛型,只需将obj 作为ValueProducer 传递。

【讨论】:

  • 如果我有几个不同的类,比如 Cube、Sphere 等,这会起作用吗?我基本上想使用通用函数来传递具有相同字段的对象,所以我知道它们可以继承自父级那么这个父级是接口还是抽象类?
【解决方案2】:

您的方法不知道T 的类型。

但是我们可以说 T 是一些扩展的类

public class GenericCube {
    public String value;
    }

所以,现在我们可以访问value,因为我们知道它

public <T extends GenericCube> void setPosition(T obj){
    System.out.println(obj);
    System.out.println(obj.value);
}

【讨论】:

  • 仍然不确定GenericCube 是否应该是通用的?可能有点混乱
  • 当然。我的错误
【解决方案3】:

我发现我可以使用反射方法访问该字段并转换为我需要的对象。使用带有该字段的抽象类支持这一点,以便从该对象继承的所有对象都可以使用该函数。

public <T> void setPosition(T object) {
   Field xField = object.getClass().getField("x");
   Field boxField = object.getClass().getField("boundBox");
   float xpos = (float)xField.get(object);
   BoundingBox box = (BoundingBox)boxField.get(object);
}

我愿意接受批评,但这与从我的抽象基类继承的多个类一起工作得很好。采用这种方法的原因是,另一个类可以与这些其他类一起工作,而无需创建多个函数,从而为想要创建自己的从抽象类继承的类的用户提供了灵活性。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-30
    • 2017-08-31
    • 2023-03-07
    • 1970-01-01
    相关资源
    最近更新 更多