泛型中的自限定
自限定顾名思义就是自己限定自己,但是具体是1.怎么限定,2.限定什么,我们先看下面的代码:
class Other {}
class BasicOther extends BasicHolder<Other> {}
public class Unconstrained {
@SuppressWarnings("unused")
public static void main(String[] args)
{
BasicOther b = new BasicOther();
BasicOther b2 = new BasicOther();
b.set(new Other());
Other other = b.get();
b.f();
}
}
从上面的代码可以看出,BasicOther类通过继承了将Other作为其泛型参数的BasicHoler从而可以将Other类作为.set()的参数和.get()的返回类型,下面再来看一段代码:
class SelfBounded<T extends SelfBounded<T>>
{
T element;
SelfBounded<T> set(T arg)
{
element = arg;
return this;
}
T get() { return element;}
}
class A extends SelfBounded<A>{}
class B extends SelfBounded<A>{}
class C extends SelfBounded<C>
{
C setAndGet(C arg)
{
set(arg);
return get();
}
}
public class SelfBounding {
public static void main(String[] args)
{
A a = new A();
a.set(new A());
a = a.set(new A()).get();
a = a.get();
//在a中泛型参数的类型就是A
C c = new C();
c = c.setAndGet(new C());
//在C类的setAndGet方法中调用了基类的set方法,这个时候泛型的类型限定就起了作用
}
}
按照上面三种方法进行子类的创建都是可行的,最主要是要满足基类(SelfBounded)中泛型参数的要求
class D {}
class E extends SelfBounded<D> {}
上面这样是不行的因为SelfBounded是需要一个有边界类作为参数,而不是一个原始类。下面的:
class F extends SelfBounded {};
直接继承了原型的SelfBounded,直接忽略了泛型,也是会产生警告的,但是可以产生编译,也就是说自限定并不是强制的。
简单的总结一下自限定的意义就是:强制将正在定义的类当作参数传递给基类。
下面用一段代码证明自限定的并不是强制执行的:
class NoSelfBounded<T>
//注意这个地方所用的泛型参数并不是自限定了
{
T element;
NoSelfBounded<T> set(T arg)
{
element = arg;
return this;
}
T get()
{
return element;
}
}
class A2 extends NoSelfBounded<A2>{}
class B2 extends NoSelfBounded<A2>{}
class C2 extends NoSelfBounded<C2>
{
C2 setAndGet(C2 arg)
{
set(arg);
return get();
}
}
没有使用自限定的代码和之前的比起来大同小异,但是下面的代码就不一样了:
class D2{}
class E2 extends NoSelfBounded<D2>{}
现在使用原始类型作为泛型参数也是可行的了。
最后说一说自限定用于方法的情况
直接上代码:
class SelfBounded<T extends SelfBounded<T>>
{
T element;
SelfBounded<T> set(T arg)
{
element = arg;
return this;
}
T get() { return element;}
}
class A extends SelfBounded<A>{}
class SelfBoudingMethods
{
static <T extends SelfBounded<T>> T f(T arg)
{
return arg.set(arg).get();
}
public static void main(String[] args)
{
A a = f(new A());
}
}
简单来说就是将自限定的语法用在方法参数上,但是与自限定类不同的是,下面的代码将会出现错误:
class SelfBounded<T extends SelfBounded<T>>
{
T element;
SelfBounded<T> set(T arg)
{
element = arg;
return this;
}
T get() { return element;}
}
class A extends SelfBounded<A>{}
class B extends SelfBounded<A>{}
class SelfBoudingMethods
{
static <T extends SelfBounded<T>> T f(T arg)
{
return arg.set(arg).get();
}
public static void main(String[] args)
{
B a = f(new B());
//上面一行的代码将导致无法编译
}
}
此时对B的自限定和类的继承不同,之前类的继承时
class A2 extends NoSelfBounded<A2>{}
class B2 extends NoSelfBounded<A2>{}
仅仅是类与类之间的继承,并不存在参数的检查。
最后总结一下:自限定,通过
还没有评论,来说两句吧...