public abstract class OuterClass<OT extends OuterClass<OT>> {
public <C extends OuterClass<?>> C parse(Class<C> clazz) {
if (clazz.isInstance(this)) {
return (C) this;
}
return null;
}
public abstract class InnerClass<CT extends InnerClass<CT> {
public <C extends InnerClass<?>> C parse(Class<C> clazz) {
if (clazz.isInstance(this)) {
return (C) this;
}
return null;
}
}
}
OuterClass<?> oInstance;
InnerClass<?> iInstance;
在上面的例子中,iInstance
变量工作正常。但是,iInstance
变量在添加泛型部分时显示错误
在原始类型
上输入类型参数
如果我从变量中删除了泛型部分,那么下面的测试用例将失败并出现类型错误
public class ExtendedOuter extends OuterClass<ExtendedOuter> {
}
// This only works on OuterClass<?> and not on OuterClass
ExtendedOuter eInstance = oInstance.parse(ExtendedOuter.class);
找到:OuterClass,必需:ExtendedOuter
静态/外部类没有问题,因为它们可以定义为ClassName<?>
,但不能使用<?>
定义非静态内部类
如何在不<?>
静态的情况下将iInstance
添加到InnerClass
?
修改 让我举几个例子说明为什么这些类使用它们的扩展版本作为泛型。
public abstract class OuterClass<OT extends OuterClass<OT>> {
public abstract OT returnMe();
}
public class ExtendedOuter extends OuterClass<ExtendedOuter> {
@Override
public ExtendedOuter returnMe() {
return this;
}
}
如果我只是在抽象版本上创建了返回类型OuterClass
,则上面的示例将不起作用。如果是这样的话,任何扩展版本都必须在使用这种方法时进行铸造,这种方法并不理想。
在<CT>
<T extends OuterClass<CT>>
后,AndroidStudio也出现了错误
参数OT不在其范围内
执行ClassName extends OuterClass<ClassName>
时,此错误会显示在扩展类中。换句话说,它只能在抽象类上使用<T extends OuterClass>
。
答案 0 :(得分:0)
类似于之前的post我展示了一个构建器模式,它使用泛型类型和继承来减少继承情况下的实际代码,这对于非静态类也是可能的。因此,我相应地修改了构建器示例以避免静态内部类:
带有父级构建器的父类:
public abstract class TestParam<Z>
{
public abstract class CommonBuilder<T extends CommonBuilder<T>>
{
protected final String a;
protected final String b;
protected final String c;
protected Z z = null;
public CommonBuilder(String a, String b, String c)
{
this.a = a;
this.b = b;
this.c = c;
}
@SuppressWarnings("unchecked")
public T withOptionalZ(Z z)
{
this.z = z;
return (T)this;
}
@SuppressWarnings("hiding")
public abstract <T> T build();
}
protected String name;
protected String a;
protected String b;
protected String c;
protected Z z = null;
protected TestParam() {
}
protected TestParam(String name, String a, String b, String c)
{
this.name = name;
this.a = a;
this.b = b;
this.c = c;
}
protected TestParam(String name, String a, String b, String c, Z z)
{
this.name = name;
this.a = a;
this.b = b;
this.c = c;
this.z = z;
}
public String getA()
{
return a;
}
public String getB()
{
return b;
}
public String getC()
{
return c;
}
protected abstract String getContent();
@Override
public String toString()
{
return name+"[A: " + a + ", B: " + b + ", C: " + c + (z != null ? ", Z: " + z.toString() : "") + getContent() +"]";
}
}
具有非静态构建器的子类看起来像这样:
@SuppressWarnings({"hiding", "unchecked"})
public class TestParamA<D,E,Z> extends TestParam<Z>
{
public class Builder<T extends TestParamA<D,E,Z>,
B extends TestParamA<D,E,Z>.Builder<? extends TestParamA<D,E,Z>, ? extends B, D, E>,
D,E>
extends TestParam<Z>.CommonBuilder<Builder<TestParamA<D,E,Z>,B, D,E>>
{
protected D d;
protected E e;
public Builder(String a, String b, String c)
{
super(a, b, c);
}
public B withD(D d)
{
this.d = d;
return (B)this;
}
public B withE(E e)
{
this.e = e;
return (B)this;
}
@Override
public <T> T build()
{
TestParamA<D,E,Z> t = new TestParamA<>("TestParamA", a, b, c, z, d, e);
return (T)t;
}
}
protected D d;
protected E e;
public TestParamA() {
super();
}
protected TestParamA(String name, String a, String b, String c, Z z, D d, E e)
{
super(name, a, b, c, z);
this.d = d;
this.e = e;
}
public D getD()
{
return d;
}
public E getE()
{
return e;
}
@Override
protected String getContent()
{
return ", D: " + d + ", E: " + e;
}
}
要测试此外部/内部类的功能,您可以实现以下内容:
public class Main
{
public static void main(String ... args)
{
TestParamA<D,E,String> a = new TestParamA<>().new Builder<>("a","b","c").withD(new D()).withE(new E()).build();
TestParamB<F,G,String> b = new TestParamB<>().new Builder<>("a","b","c").withF(new F()).withG(new G()).withOptionalZ("z").build();
TestParam<String> c = new TestParamA<>().new Builder<>("a","b","c").withD(new D()).withE(new E()).withOptionalZ("z").build();
TestParam<?> d = new TestParamB<>().new Builder<>("a","b","c").withF(new F()).withG(new G()).build();
test(a);
test(b);
test(c);
test(d);
TestParam<?>.CommonBuilder<? extends TestParam<?>.CommonBuilder<?>> builder =
new TestParamA<>().new Builder<>("a", "b", "c").withD(new D()).withE(new E());
test(builder);
// or a bit shorter
TestParam<?>.CommonBuilder<?> builder2 =
new TestParamB<>().new Builder<>("a", "b", "c").withF(new F()).withG(new G());
test(builder2);
}
public static void test(TestParamA<?,?,?> testParam)
{
System.out.println("Test for ParamA: " + testParam.toString());
}
public static void test(TestParamB<?,?,?> testParam)
{
System.out.println("Test for ParamB: " + testParam.toString());
}
public static void test(TestParam<?> testParam)
{
System.out.println("Test for Param: " + testParam.toString());
}
public static void test(TestParam<?>.CommonBuilder<?> builder)
{
System.out.println("Test for CommonBuilder: " + builder.build().toString());
}
}
TestParamB
与TestParamA
相同 - 它仅包含F
和G
的varialbe和builder-methods,而不是D
和E
。此外,D
,E
,F
和G
只是具有简单toString()
实现的类,只返回简单的类名。
这将打印以下输出:
Test for ParamA: TestParamA[A: a, B: b, C: c, D: D, E: E]
Test for ParamB: TestParamB[A: a, B: b, C: c, Z: z, F: F, G: G]
Test for Param: TestParamA[A: a, B: b, C: c, Z: z, D: D, E: E]
Test for Param: TestParamB[A: a, B: b, C: c, F: F, G: G]
Test for CommonBuilder: TestParamA[A: a, B: b, C: c, D: D, E: E]
Test for CommonBuilder: TestParamB[A: a, B: b, C: c, F: F, G: G]
答案 1 :(得分:0)
但是,添加泛型时iInstance变量显示错误 部分
在原始类型
上输入类型参数
首先,这不是你应该得到的问题,因为范围内没有定义InnerClass
。作为一个内部类,它的范围在外部类的范围内。因此,当它在外部类之外时,您需要使用外部类明确限定它,否则它将为您提供InnerClass
符号未找到错误。所以你没有显示你的真实代码(也许你在某处有另一个InnerClass
)或者没有显示你真正的错误。
如果我从变量中删除泛型部分,那么下面的测试 案例将因类型错误而失败
当您使用原始类型访问成员时,会关闭这些成员上的所有泛型。因此.parse()
被删除为public OuterClass parse(Class clazz)
(即使方法未使用CT
也是如此),这就是为什么oInstance.parse(ExtendedOuter.class)
返回类型OuterClass
的原因与ExtendedOuter
不兼容。
如何在不使InnerClass静态的情况下将
<?>
添加到iInstance?
赞OuterClass<?>.InnerClass<?>
或OuterClass<Something>.InnerClass<SomethingElse>