Java泛型中基于其他两种类型推断返回类型的更简单方法
我在Java中尝试做的基本上是拥有一个由两个其他接口组合而成的接口(因此它有来自这两个接口的方法,但没有自己的),然后两个子接口可以一次交换一个,所以当进行更改时,两个接口之一的所有方法都会保留,而来自另一个接口的所有方法都被交换为不同的方法。由于泛型正在处理切换,因此不需要强制转换来获得新方法或删除旧方法
例如,我们从接口{getStartState().methodLeftA().methodRightA().selectLeftType(B).methodLeftB().methodRightA()
我已经为此设计了一个可行的实现,我将在这里进一步展示,但代码非常冗长。只需做A、B和C类型。已经有30个文件,要添加D,需要添加16个新文件和编辑17个现有文件。在这之后添加E需要添加20个新文件和编辑26个现有文件。因此,虽然这对一小部分选项来说是可以接受的,但它很快就会失去控制,而不仅仅是几个选项。所以我的问题是,有没有更简单、更干净的方法
注意:这是使用Java7构建的,但我对使用Java8特性的实现持开放态度
我当前的实现如下(如我前面所说,它很长):
BaseImpl。爪哇
package test;
class BaseImpl<CURRENT_INTERFACE> implements Combo<CURRENT_INTERFACE> {
protected <T extends Combo<?>> T
selectLeftTypeBase(Selector<?, ?, ?, ?, ?, ?> selector, Class<T> cls) {
System.out.println("Switch left type. New class: " + cls.getSimpleName());
return selectTypeBase(cls);
}
protected <T extends Combo<?>> T
selectRightTypeBase(Selector<?, ?, ?, ?, ?, ?> selector, Class<T> cls) {
System.out.println("Switch right type. New class: " + cls.getSimpleName());
return selectTypeBase(cls);
}
private <T extends Combo<?>> T selectTypeBase(Class<T> cls) {
try {
return cls.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
@SuppressWarnings("unchecked")
public CURRENT_INTERFACE methodLeftA() {
System.out.println("Left A specific stuff.");
return (CURRENT_INTERFACE) this;
}
@SuppressWarnings("unchecked")
public CURRENT_INTERFACE methodLeftB() {
System.out.println("Left B specific stuff.");
return (CURRENT_INTERFACE) this;
}
@SuppressWarnings("unchecked")
public CURRENT_INTERFACE methodLeftC() {
System.out.println("Left C specific stuff.");
return (CURRENT_INTERFACE) this;
}
@SuppressWarnings("unchecked")
public CURRENT_INTERFACE methodRightA() {
System.out.println("Right A specific stuff.");
return (CURRENT_INTERFACE) this;
}
@SuppressWarnings("unchecked")
public CURRENT_INTERFACE methodRightB() {
System.out.println("Right B specific stuff.");
return (CURRENT_INTERFACE) this;
}
@SuppressWarnings("unchecked")
public CURRENT_INTERFACE methodRightC() {
System.out.println("Right C specific stuff.");
return (CURRENT_INTERFACE) this;
}
}
选择器。爪哇
package test;
public final class Selector<
LEFT_A_TYPE extends LeftA<LEFT_A_TYPE> & Combo<LEFT_A_TYPE>,
RIGHT_A_TYPE extends RightA<RIGHT_A_TYPE> & Combo<RIGHT_A_TYPE>,
LEFT_B_TYPE extends LeftB<LEFT_B_TYPE> & Combo<LEFT_B_TYPE>,
RIGHT_B_TYPE extends RightB<RIGHT_B_TYPE> & Combo<RIGHT_B_TYPE>,
LEFT_C_TYPE extends LeftC<LEFT_C_TYPE> & Combo<LEFT_C_TYPE>,
RIGHT_C_TYPE extends RightC<RIGHT_C_TYPE> & Combo<RIGHT_C_TYPE>> {
public static final Selector<AA, AA, BA, AB, CA, AC> A =
new Selector<AA, AA, BA, AB, CA, AC>(
AAImpl.class, AAImpl.class,
BAImpl.class, ABImpl.class,
CAImpl.class, ACImpl.class);
public static final Selector<AB, BA, BB, BB, CB, BC> B =
new Selector<AB, BA, BB, BB, CB, BC>(
ABImpl.class, BAImpl.class,
BBImpl.class, BBImpl.class,
CBImpl.class, BCImpl.class);
public static final Selector<AC, CA, BC, CB, CC, CC> C =
new Selector<AC, CA, BC, CB, CC, CC>(
ACImpl.class, CAImpl.class,
BCImpl.class, CBImpl.class,
CCImpl.class, CCImpl.class);
private final Class<? extends LEFT_A_TYPE> leftATypeClass;
private final Class<? extends LEFT_B_TYPE> leftBTypeClass;
private final Class<? extends LEFT_C_TYPE> leftCTypeClass;
private final Class<? extends RIGHT_A_TYPE> rightATypeClass;
private final Class<? extends RIGHT_B_TYPE> rightBTypeClass;
private final Class<? extends RIGHT_C_TYPE> rightCTypeClass;
private Selector(
Class<? extends LEFT_A_TYPE> leftATypeClass,
Class<? extends RIGHT_A_TYPE> rightATypeClass,
Class<? extends LEFT_B_TYPE> leftBTypeClass,
Class<? extends RIGHT_B_TYPE> rightBTypeClass,
Class<? extends LEFT_C_TYPE> leftCTypeClass,
Class<? extends RIGHT_C_TYPE> rightCTypeClass) {
this.leftATypeClass = leftATypeClass;
this.leftBTypeClass = leftBTypeClass;
this.leftCTypeClass = leftCTypeClass;
this.rightATypeClass = rightATypeClass;
this.rightBTypeClass = rightBTypeClass;
this.rightCTypeClass = rightCTypeClass;
}
public Class<? extends LEFT_A_TYPE> getLeftATypeClass() {
return leftATypeClass;
}
public Class<? extends LEFT_B_TYPE> getLeftBTypeClass() {
return leftBTypeClass;
}
public Class<? extends LEFT_C_TYPE> getLeftCTypeClass() {
return leftCTypeClass;
}
public Class<? extends RIGHT_A_TYPE> getRightATypeClass() {
return rightATypeClass;
}
public Class<? extends RIGHT_B_TYPE> getRightBTypeClass() {
return rightBTypeClass;
}
public Class<? extends RIGHT_C_TYPE> getRightCTypeClass() {
return rightCTypeClass;
}
}
Util。爪哇
package test;
public final class Util {
private Util() {}
public static AA getStartState() {
return new AAImpl();
}
}
左边。爪哇
package test;
public interface Left<CURRENT_INTERFACE> { }
对。爪哇
package test;
public interface Right<CURRENT_INTERFACE> { }
组合。爪哇
package test;
public interface Combo<CURRENT_INTERFACE> extends
Left<CURRENT_INTERFACE>,
Right<CURRENT_INTERFACE> { }
左撇子。爪哇
package test;
public interface LeftA<CURRENT_INTERFACE> extends Left<CURRENT_INTERFACE> {
public CURRENT_INTERFACE methodLeftA();
public <T extends Combo<T> & LeftA<T>> T
selectRightType(Selector<T, ?, ?, ?, ?, ?> selector);
}
左B。爪哇
package test;
public interface LeftB<CURRENT_INTERFACE> extends Left<CURRENT_INTERFACE> {
public CURRENT_INTERFACE methodLeftB();
public <T extends Combo<T> & LeftB<T>> T
selectRightType(Selector<?, ?, T, ?, ?, ?> selector);
}
左C。爪哇
package test;
public interface LeftC<CURRENT_INTERFACE> extends Left<CURRENT_INTERFACE> {
public CURRENT_INTERFACE methodLeftC();
public <T extends Combo<T> & LeftC<T>> T
selectRightType(Selector<?, ?, ?, ?, T, ?> selector);
}
好的。爪哇
package test;
public interface RightA<CURRENT_INTERFACE> extends Right<CURRENT_INTERFACE> {
public CURRENT_INTERFACE methodRightA();
public <T extends Combo<T> & RightA<T>> T
selectLeftType(Selector<?, T, ?, ?, ?, ?> selector);
}
对。爪哇
package test;
public interface RightB<CURRENT_INTERFACE> extends Right<CURRENT_INTERFACE> {
public CURRENT_INTERFACE methodRightB();
public <T extends Combo<T> & RightB<T>> T
selectLeftType(Selector<?, ?, ?, T, ?, ?> selector);
}
对。爪哇
package test;
public interface RightC<CURRENT_INTERFACE> extends Right<CURRENT_INTERFACE> {
public CURRENT_INTERFACE methodRightC();
public <T extends Combo<T> & RightC<T>> T
selectLeftType(Selector<?, ?, ?, ?, ?, T> selector);
}
AA。爪哇
package test;
public interface AA extends Combo<AA>, LeftA<AA>, RightA<AA> { }
啊。爪哇
package test;
final class AAImpl extends BaseImpl<AA> implements AA {
@Override
public <T extends Combo<T> & LeftA<T>> T
selectRightType(Selector<T, ?, ?, ?, ?, ?> selector) {
return selectRightTypeBase(selector, selector.getLeftATypeClass());
}
@Override
public <T extends Combo<T> & RightA<T>> T
selectLeftType(Selector<?, T, ?, ?, ?, ?> selector) {
return selectLeftTypeBase(selector, selector.getRightATypeClass());
}
}
AB.java
package test;
public interface AB extends Combo<AB>, LeftA<AB>, RightB<AB> { }
阿宾普。爪哇
package test;
final class ABImpl extends BaseImpl<AB> implements AB {
@Override
public <T extends Combo<T> & LeftA<T>> T
selectRightType(Selector<T, ?, ?, ?, ?, ?> selector) {
return selectRightTypeBase(selector, selector.getLeftATypeClass());
}
@Override
public <T extends Combo<T> & RightB<T>> T
selectLeftType(Selector<?, ?, ?, T, ?, ?> selector) {
return selectLeftTypeBase(selector, selector.getRightBTypeClass());
}
}
AC.java
package test;
public interface AC extends Combo<AC>, LeftA<AC>, RightC<AC> { }
阿辛普。爪哇
package test;
final class ACImpl extends BaseImpl<AC> implements AC {
@Override
public <T extends Combo<T> & LeftA<T>> T
selectRightType(Selector<T, ?, ?, ?, ?, ?> selector) {
return selectLeftTypeBase(selector, selector.getLeftATypeClass());
}
@Override
public <T extends Combo<T> & RightC<T>> T
selectLeftType(Selector<?, ?, ?, ?, ?, T> selector) {
return selectRightTypeBase(selector, selector.getRightCTypeClass());
}
}
巴。爪哇
package test;
public interface BA extends Combo<BA>, LeftB<BA>, RightA<BA> { }
拜姆普。爪哇
package test;
final class BAImpl extends BaseImpl<BA> implements BA {
@Override
public <T extends Combo<T> & LeftB<T>> T
selectRightType(Selector<?, ?, T, ?, ?, ?> selector) {
return selectRightTypeBase(selector, selector.getLeftBTypeClass());
}
@Override
public <T extends Combo<T> & RightA<T>> T
selectLeftType(Selector<?, T, ?, ?, ?, ?> selector) {
return selectLeftTypeBase(selector, selector.getRightATypeClass());
}
}
BB。爪哇
package test;
public interface BB extends Combo<BB>, LeftB<BB>, RightB<BB> { }
BBImpl。爪哇
package test;
final class BBImpl extends BaseImpl<BB> implements BB {
@Override
public <T extends Combo<T> & LeftB<T>> T
selectRightType(Selector<?, ?, T, ?, ?, ?> selector) {
return selectRightTypeBase(selector, selector.getLeftBTypeClass());
}
@Override
public <T extends Combo<T> & RightB<T>> T
selectLeftType(Selector<?, ?, ?, T, ?, ?> selector) {
return selectLeftTypeBase(selector, selector.getRightBTypeClass());
}
}
公元前。爪哇
package test;
public interface BC extends Combo<BC>, LeftB<BC>, RightC<BC> { }
B简单。爪哇
package test;
final class BCImpl extends BaseImpl<BC> implements BC {
@Override
public <T extends Combo<T> & LeftB<T>> T
selectRightType(Selector<?, ?, T, ?, ?, ?> selector) {
return selectRightTypeBase(selector, selector.getLeftBTypeClass());
}
@Override
public <T extends Combo<T> & RightC<T>> T
selectLeftType(Selector<?, ?, ?, ?, ?, T> selector) {
return selectLeftTypeBase(selector, selector.getRightCTypeClass());
}
}
CA.java
package test;
public interface CA extends Combo<CA>, LeftC<CA>, RightA<CA> { }
坎普。爪哇
package test;
final class CAImpl extends BaseImpl<CA> implements CA {
@Override
public <T extends Combo<T> & LeftC<T>> T
selectRightType(Selector<?, ?, ?, ?, T, ?> selector) {
return selectRightTypeBase(selector, selector.getLeftCTypeClass());
}
@Override
public <T extends Combo<T> & RightA<T>> T
selectLeftType(Selector<?, T, ?, ?, ?, ?> selector) {
return selectLeftTypeBase(selector, selector.getRightATypeClass());
}
}
CB。爪哇
package test;
public interface CB extends Combo<CB>, LeftC<CB>, RightB<CB> { }
CBImpl。爪哇
package test;
final class CBImpl extends BaseImpl<CB> implements CB {
@Override
public <T extends Combo<T> & LeftC<T>> T
selectRightType(Selector<?, ?, ?, ?, T, ?> selector) {
return selectRightTypeBase(selector, selector.getLeftCTypeClass());
}
@Override
public <T extends Combo<T> & RightB<T>> T
selectLeftType(Selector<?, ?, ?, T, ?, ?> selector) {
return selectLeftTypeBase(selector, selector.getRightBTypeClass());
}
}
抄送。爪哇
package test;
public interface CC extends Combo<CC>, LeftC<CC>, RightC<CC> { }
CCImpl。爪哇
package test;
final class CCImpl extends BaseImpl<CC> implements CC {
@Override
public <T extends Combo<T> & LeftC<T>> T
selectRightType(Selector<?, ?, ?, ?, T, ?> selector) {
return selectRightTypeBase(selector, selector.getLeftCTypeClass());
}
@Override
public <T extends Combo<T> & RightC<T>> T
selectLeftType(Selector<?, ?, ?, ?, ?, T> selector) {
return selectLeftTypeBase(selector, selector.getRightCTypeClass());
}
}
所有这些代码将允许我实现以下目标:
import static test.Selector.*;
import static test.Util.*;
public class Main {
public static void main(String[] args) {
getStartState()
.methodLeftA()
.methodRightA()
.selectLeftType(B)
.methodLeftB()
.methodRightA()
.selectRightType(B)
.methodLeftB()
.methodRightB()
.selectLeftType(C)
.methodLeftC()
.methodRightB()
.selectRightType(A)
.methodLeftC()
.methodRightA()
.selectLeftType(B)
.methodLeftB()
.selectLeftType(A)
.methodRightA();
}
}
共 (0) 个答案