pvg*_*ijn 17 java generics polymorphism casting
是否可以将Java中的对象转换为组合泛型类型?
我有一个方法,如:
public static <T extends Foo & Bar> void doSomething(T object) {
//do stuff
}
Run Code Online (Sandbox Code Playgroud)
如果我有一个实现两个接口的类(Foo和Bar),则调用此方法没有问题.
问题是,当我需要调用此方法时,我需要传递给它的对象,java.lang.Object并且我需要将其转换为使编译器满意.但我无法弄清楚如何进行演员表演.
编辑:
问题在于这样的功能:
public void problemFunction (Object o) {
if ( o instanceof Foo && o instanceof Bar) {
doSomething((Problematic cast) o);
}
}
Run Code Online (Sandbox Code Playgroud)
}
Ron*_*n C 20
Java 8引入了使用附加边界进行转换的可能性.您可以将Objecta转换class为多个interfaces(或多个interfaces).
所以这:
doSomething((Problematic cast) o);
Run Code Online (Sandbox Code Playgroud)
简单地说到这个:
doSomething((Foo & Bar) o);
Run Code Online (Sandbox Code Playgroud)
eri*_*son 13
不幸的是,您无法通过合法演员来满足这种情况.必须有一个已知的类型来实现您需要的所有接口作为边界,以便您可以转换为它.可能是您为此目的创建的类型,或某些现有类型.
interface Baz extends Foo, Bar { }
public void caller(Object w) {
doSomething((Baz) w);
}
Run Code Online (Sandbox Code Playgroud)
如果已知其他类型,例如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));
}
Run Code Online (Sandbox Code Playgroud)
public static <T extends Foo & Bar> void doSomething(T object)
Run Code Online (Sandbox Code Playgroud)
这似乎表示您将对相关对象执行多个操作.
我认为,如果你在对象上执行的所需操作足够明显,可以跨接口分离,那么它们就足够了,值得拥有自己的方法.
您可能需要重新构造此代码以调用单独的方法来执行所需的操作.从客户的角度来看,这可能最终使整个操作更加清晰.
代替:
public void problemFunction (Object o) {
if (o instanceof Foo && o instanceof Bar) {
doSomething((Problematic cast) o);
}
}
Run Code Online (Sandbox Code Playgroud)
它成为了:
public void problemFunction(Object o) {
if (o instanceof Foo && o instanceof Bar) {
fooifySomething((Foo) o);
baratizeSomething((Bar) o);
}
}
Run Code Online (Sandbox Code Playgroud)
小智 6
通过将union类型编码为方法的类型参数的可怕方法,可以"向上转换"为union类型; 为你的例子,你可以写
private <Q extends Foo & Bar> Q upcast(final Object in) {
return (Q) in;
}
// ... elsewhere...
if (myObject instanceof Foo && myObject instanceof Bar) {
doSomething(upcast(myObject));
}
Run Code Online (Sandbox Code Playgroud)