Java 使用抽象参数调用通用接口
Java generic interface calling with abstract parameter
我知道有很多类似的问题,但如果可能的话,我没能找到一个干净整洁的解决方案。
我正在实现一个带有抽象类型的 subclasses 的通用接口。问题是,当我调用它们时,我要么必须在 switch/case 中进行类型转换,要么在接口实现中的每个方法中进行类型转换,我想不出一个好的和干净的方法......我会更好写下一个简短的例子。
// An abstract type with 2 implementations...
public abstract class ObjTypeAbstract {}
public class ObjType extends ObjTypeAbstract {}
public class ScriptType extends ObjTypeAbstract {}
现在两种类型的处理器都带有一个接口
interface ProcessorInterface<T extends ObjTypeAbstract> {
public void abcMethod(T obj);
}
public class ObjProcessor implements ProcessorInterface<ObjType> {
public void abcMethod(ObjType obj) {}
}
public class ScriptProcessor implements ProcessorInterface<ScriptType> {
public void abcMethod(ScriptType obj) {}
}
我正在苦苦挣扎的是一种基于 ObjAbstractType 调用这些处理器的方法。我有一个 class 作为中间件的服务器?或者我应该怎么称呼它。:
想法是通过单个 switch/case:
简单地获得正确的处理器
public class Processor {
private ProcessorInterface objProcessor = new ObjProcessor();
private ProcessorInterface scriptProcessor = new ScriptProcessor();
public methodAbc(ObjAbstractType obj) {
getProcessor(obj).abcMethod(obj);
}
private ProcessorInterface getProcessor(ObjAbstractType obj) {
if (obj instanceof ObjType) {
return objectProcessor;
} else if (obj instanceof ScriptType) {
return scriptProcessor;
}
return nullProcessor;
}
}
这就是我想要的,它还负责将 objAbstract 类型转换为 abcMethod 的实际类型,问题是它会导致不会破坏代码的 RawType 警告,但我会想摆脱它。
这就是我卡住的地方...因为如果我将处理器转换为特定类型,如下所示:
private ProcessorInterface<ObjType> objProcessor = new ObjProcessor();
private ProcessorInterface<ScriptType> scriptProcessor = new ScriptProcessor();
我无法从 getProcessor 方法中 return 抽象一个,因此我必须使用 ObjAbstractType 及其所有方法来实现这些接口,并在每个处理器的所有方法中进行类型转换,例如:
public class ScriptProcessor implements ProcessorInterface<ObjAbstractType> {
public void abcMethod(ObjAbstractType obj) {
ScriptType scr = (ScriptType) obj;
}
}
另一个解决方案可能是在处理器中间件 class 中有一个 switch/case 并在其中转换 ObjAbstractType ,但我必须在 abcMethod 和所有其他方法中或从 getProcessor 方法中编写该开关 returns 处理器和转换的 ObjType...所以我必须 return 一些包含两者的 dto。 :/
您是否有任何想法/模式可以帮助我摆脱 RawType 调用警告而无需使用更多 switch/case 或类型转换扩展代码?
祝你有美好的一天,大卫,我很乐意进行任何讨论。
您需要一种方法来存储 ObjTypeAbstract
class 和 ProcessorInterface
实例之间的映射。
您可以使用 Map
将 ObjTypeAbstract
s(作为键)关联到 ProcessorInterface
s(作为值)。
关于原始类型问题,您可以将 ProcessorInterface<? extends ObjTypeAbstract>
用于声明的变量,但您仍然需要对 ProcessorInterface<ObjTypeAbstract>
执行不安全的强制转换才能调用 ProcessorInterface.abcMethod()
作为参数 a ObjTypeAbstract
声明的类型。
这种转换对于您的实际设计是不可避免的。
它可以给出类似的东西:
public class Processor {
private Map<Class<? extends ObjTypeAbstract>, ProcessorInterface<? extends ObjTypeAbstract >> map = new HashMap<>();
public Processor(){
map.put(ObjType.class, new ObjProcessor());
map.put(ScriptType.class, new ScriptProcessor());
}
public void methodAbc(ObjTypeAbstract obj) {
@SuppressWarnings("unchecked")
ProcessorInterface<ObjTypeAbstract> processorInterface = (ProcessorInterface<ObjTypeAbstract>) map.get(obj.getClass());
processorInterface.abcMethod(obj);
}
}
我认为没有更优雅的方式来绕过某种形式的 instanceof
逻辑。但是,如果您向 getProcessor
.
添加一些类型,则不需要强制转换
public <T extends ObjTypeAbstract> ProcessorInterface<T> getProcessor(Class<T> theClass) {
if (theClass.isAssignableFrom(ObjType.class)) {
return objProcessor;
} else if (theClass.isAssignableFrom(ScriptType.class)) {
return scriptProcessor;
}
return null;
}
然后可以这样调用:
ProcessorInterface<ScriptType> scriptProcessor = new Processor().getProcessor(ScriptType.class);
ProcessorInterface<ObjType> objProcessor = new Processor().getProcessor(ObjType.class);
我知道有很多类似的问题,但如果可能的话,我没能找到一个干净整洁的解决方案。 我正在实现一个带有抽象类型的 subclasses 的通用接口。问题是,当我调用它们时,我要么必须在 switch/case 中进行类型转换,要么在接口实现中的每个方法中进行类型转换,我想不出一个好的和干净的方法......我会更好写下一个简短的例子。
// An abstract type with 2 implementations...
public abstract class ObjTypeAbstract {}
public class ObjType extends ObjTypeAbstract {}
public class ScriptType extends ObjTypeAbstract {}
现在两种类型的处理器都带有一个接口
interface ProcessorInterface<T extends ObjTypeAbstract> {
public void abcMethod(T obj);
}
public class ObjProcessor implements ProcessorInterface<ObjType> {
public void abcMethod(ObjType obj) {}
}
public class ScriptProcessor implements ProcessorInterface<ScriptType> {
public void abcMethod(ScriptType obj) {}
}
我正在苦苦挣扎的是一种基于 ObjAbstractType 调用这些处理器的方法。我有一个 class 作为中间件的服务器?或者我应该怎么称呼它。:
想法是通过单个 switch/case:
简单地获得正确的处理器public class Processor {
private ProcessorInterface objProcessor = new ObjProcessor();
private ProcessorInterface scriptProcessor = new ScriptProcessor();
public methodAbc(ObjAbstractType obj) {
getProcessor(obj).abcMethod(obj);
}
private ProcessorInterface getProcessor(ObjAbstractType obj) {
if (obj instanceof ObjType) {
return objectProcessor;
} else if (obj instanceof ScriptType) {
return scriptProcessor;
}
return nullProcessor;
}
}
这就是我想要的,它还负责将 objAbstract 类型转换为 abcMethod 的实际类型,问题是它会导致不会破坏代码的 RawType 警告,但我会想摆脱它。
这就是我卡住的地方...因为如果我将处理器转换为特定类型,如下所示:
private ProcessorInterface<ObjType> objProcessor = new ObjProcessor();
private ProcessorInterface<ScriptType> scriptProcessor = new ScriptProcessor();
我无法从 getProcessor 方法中 return 抽象一个,因此我必须使用 ObjAbstractType 及其所有方法来实现这些接口,并在每个处理器的所有方法中进行类型转换,例如:
public class ScriptProcessor implements ProcessorInterface<ObjAbstractType> {
public void abcMethod(ObjAbstractType obj) {
ScriptType scr = (ScriptType) obj;
}
}
另一个解决方案可能是在处理器中间件 class 中有一个 switch/case 并在其中转换 ObjAbstractType ,但我必须在 abcMethod 和所有其他方法中或从 getProcessor 方法中编写该开关 returns 处理器和转换的 ObjType...所以我必须 return 一些包含两者的 dto。 :/
您是否有任何想法/模式可以帮助我摆脱 RawType 调用警告而无需使用更多 switch/case 或类型转换扩展代码? 祝你有美好的一天,大卫,我很乐意进行任何讨论。
您需要一种方法来存储 ObjTypeAbstract
class 和 ProcessorInterface
实例之间的映射。
您可以使用 Map
将 ObjTypeAbstract
s(作为键)关联到 ProcessorInterface
s(作为值)。
关于原始类型问题,您可以将 ProcessorInterface<? extends ObjTypeAbstract>
用于声明的变量,但您仍然需要对 ProcessorInterface<ObjTypeAbstract>
执行不安全的强制转换才能调用 ProcessorInterface.abcMethod()
作为参数 a ObjTypeAbstract
声明的类型。
这种转换对于您的实际设计是不可避免的。
它可以给出类似的东西:
public class Processor {
private Map<Class<? extends ObjTypeAbstract>, ProcessorInterface<? extends ObjTypeAbstract >> map = new HashMap<>();
public Processor(){
map.put(ObjType.class, new ObjProcessor());
map.put(ScriptType.class, new ScriptProcessor());
}
public void methodAbc(ObjTypeAbstract obj) {
@SuppressWarnings("unchecked")
ProcessorInterface<ObjTypeAbstract> processorInterface = (ProcessorInterface<ObjTypeAbstract>) map.get(obj.getClass());
processorInterface.abcMethod(obj);
}
}
我认为没有更优雅的方式来绕过某种形式的 instanceof
逻辑。但是,如果您向 getProcessor
.
public <T extends ObjTypeAbstract> ProcessorInterface<T> getProcessor(Class<T> theClass) {
if (theClass.isAssignableFrom(ObjType.class)) {
return objProcessor;
} else if (theClass.isAssignableFrom(ScriptType.class)) {
return scriptProcessor;
}
return null;
}
然后可以这样调用:
ProcessorInterface<ScriptType> scriptProcessor = new Processor().getProcessor(ScriptType.class);
ProcessorInterface<ObjType> objProcessor = new Processor().getProcessor(ObjType.class);