我应该如何对具有多个边界的Java泛型进行强制转换?

我应该如何对具有多个边界的Java泛型进行强制转换?,java,generics,casting,polymorphism,Java,Generics,Casting,Polymorphism,可以将Java中的对象强制转换为组合泛型类型吗 我有这样一种方法: public static <T extends Foo & Bar> void doSomething(T object) { //do stuff } }不幸的是,您无法通过法律手段来满足这种情况。必须有一个已知的类型来实现作为边界所需的所有接口,以便可以对其进行强制转换。可能是为此目的创建的类型,也可能是某个现有类型 interface Baz extends Foo, Bar { } pu

可以将Java中的对象强制转换为组合泛型类型吗

我有这样一种方法:

public static <T extends Foo & Bar> void doSomething(T object) {
    //do stuff
}

}

不幸的是,您无法通过法律手段来满足这种情况。必须有一个已知的类型来实现作为边界所需的所有接口,以便可以对其进行强制转换。可能是为此目的创建的类型,也可能是某个现有类型

interface Baz extends Foo, Bar { }

public void caller(Object w) {
  doSomething((Baz) w);
}
如果已知其他类型,如
Baz
,以满足边界要求,则可以测试这些类型,并在调用者中设置一个分支,通过对这些类型的转换调用
doSomething
。这不漂亮

您还可以使用委托,创建自己的类
Baz
,该类满足
doSomething
所需的边界。然后将传递到
Baz
类的实例中的对象包装起来,并将包装传递给
doSomething

private static class FooBarAdapter implements Foo, Bar {
  private final Object adaptee;
  FooBarAdapter(Object o) {
    adaptee = (Foo) (Bar) o;
  }
  public int flip() { return ((Foo) adaptee).flip(); }
  public void flop(int x) { ((Foo) adaptee).flop(x); }
  public void blort() { ((Bar) adaptee).blort(); }
}

public void problemFunction (Object o) {
  doSomething(new FooBarAdapter(o));
}

作为一种解决方法,您可以定义另一个扩展Foo和Bar的接口FooBar,并让您的类实现它。它甚至不必是顶级接口——如果您不想混乱或改装代码的其余部分,可以将其声明为私有:

private interface FooBar extends Foo, Bar {}
public void problemFunction (Object o) {
  if ( o instanceof Foo && o instanceof Bar) {
      doSomething((FooBar) o);
  }
}
它变成:

public void problemFunction(Object o) {
  if (o instanceof Foo && o instanceof Bar) {
      fooifySomething((Foo) o);
      baratizeSomething((Bar) o);
  }
}
通过将联合类型编码为方法的类型参数,可以“向上转换”到联合类型;你可以写下你的例子

private Q upcast(中的最终对象){
返回(Q)in;
}
// ... 在别处
if(myObject instanceof Foo和myObject instanceof Bar){
剂量测量(向上投射(myObject));
}

Java8引入了。您可以将
对象
强制转换为具有多个
接口
(或与多个
接口
)的

因此:

doSomething((Problematic cast) o);
简单地说:

doSomething((Foo & Bar) o);

我相信这是行不通的,因为不能保证o实际上有“implements FooBar”。我不认为Java会仅仅假设它。@ArtB答案是“并让您的类实现它。”。好主意。我用了一种稍微不同的方式。我更喜欢FooBarAdapter来访问具有两种不同类型的对象。==可以用来检查它是否是同一个对象(不必)。通过这种方式,它们是编译时类型检查。我将这种委托模式匿名/命名内部方法类组合在一起,以“强制转换”一个我知道的对象,以扩展/实现一组类和接口来满足绑定需求。请看Jon的回答:这似乎是Java语言的局限性,因为在同一JVM上运行的Scala中,这很容易,就像o.asInstanceOf[Foo with Bar]LMAO fooify一样,这对我来说是新的。唯一令人烦恼的是,它会生成一个未经检查的强制类型。然而,我使用了一个修改过的版本,它接受Foo而不是Object,并检查它实现了Bar,然后返回cast,就像抛出ClassCastException一样。
public void problemFunction(Object o) {
  if (o instanceof Foo && o instanceof Bar) {
      fooifySomething((Foo) o);
      baratizeSomething((Bar) o);
  }
}
doSomething((Problematic cast) o);
doSomething((Foo & Bar) o);