JAVA 深入理解 古怪的迴圈泛型、自限定、引數協變
阿新 • • 發佈:2019-01-11
古怪的迴圈泛型 自限定引數協變
package CuriouslyRecurringGeneric; public class BasicHolder<T> { T element; public T get() { return element; } public void set(T element) { this.element = element; } void f(){ System.out.println(element.getClass().getSimpleName()); } }
package CuriouslyRecurringGeneric; class Base{} class Derived extends Base{} interface OrdinaryGetter{ Base get(); } interface DeriveGetter extends OrdinaryGetter{ Derived get(); } //諧變返回型別 public class CovariantRreturnTypes { void test(DeriveGetter d){ Derived d2 = d.get(); } public static void main(String [] argv){ CovariantRreturnTypes crt = new CovariantRreturnTypes(); } }
package CuriouslyRecurringGeneric; class Subtyppe extends BasicHolder<Subtyppe>{} public class CRGWithBasicHolder { public static void main(String[] args){ Subtyppe st1 = new Subtyppe(), st2 = new Subtyppe(); st1.set(st2); Subtyppe st3 = st1.get(); st1.f(); } }
package CuriouslyRecurringGeneric;
interface GenericGetter<T extends GenericGetter<T>>{
T get();
}
interface Getter extends GenericGetter<Getter>{
}
public class GenericAndReturnTypes {
void test(Getter g){
Getter result = g.get();
GenericGetter gg = g.get();
}
}
package CuriouslyRecurringGeneric;
public class GenericType<T> {
//古怪的迴圈泛型
public class CuriouslyRecurringGeneric extends GenericType<CuriouslyRecurringGeneric>{
}
}
package CuriouslyRecurringGeneric;
public class NotSelfBounded<T> {
T element;
NotSelfBounded<T> set(T arg){
element = arg;
return this;
}
T get(){return element;}
public static void main(String [] argv){
NotSelfBounded<Integer> n = new NotSelfBounded<>();
NotSelfBounded<Integer> s = n.set(10);
}
}
class A2 extends NotSelfBounded<A2>{}
class B2 extends NotSelfBounded<A2>{}
class C2 extends NotSelfBounded<C2>{
C2 setAndGet(C2 arg){
set(arg);
return get();
}
}
class D2{}
class E2 extends NotSelfBounded<D2>{}
package CuriouslyRecurringGeneric;
class OrdinarySetter{
void set(Base base){
System.out.println("OrdinarySetter.set(Base base){");
}
}
class DeriveSetter extends OrdinarySetter{
void set(Derived derived){
System.out.println("DeriveSetter.set(Derived derived){");
}
}
public class OrdinaryArgments {
public static void main(String [] argv){
Base base = new Base();
Derived derived = new Derived();
DeriveSetter ds = new DeriveSetter();
ds.set(base);
ds.set(derived);
}
}
package CuriouslyRecurringGeneric;
class GenericSetter<T>{
void set(T arg){
System.out.println("GenericSetter.set(Base)");
}
}
class DerivedGS extends GenericSetter<Base>{
void set(Derived derived){
System.out.println("DerivedGS.set(Derived)");
}
}
public class PlainGenericInheritance {
public static void main(String [] argv){
Base base = new Base();
Derived derived = new Derived();
DerivedGS dgs = new DerivedGS();
dgs.set(base);
dgs.set(derived);
}
}
package CuriouslyRecurringGeneric;
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();
}
}
class D{};
//class E extends SelfBounded<D>{} //此處出錯
class F extends SelfBounded{} //OK
//自限定的類
public class SelfBounding {
public static void main(String [] argv){
A a = new A();
a.set(new A());
a.set(new A()).get();
a=a.get();
C c = new C();
c = c.setAndGet(new C());
}
}
package CuriouslyRecurringGeneric;
interface SelfBoundSetter<T extends SelfBoundSetter<T>>{
void set(T arg);
}
interface Setter extends SelfBoundSetter<Setter>{}
public class SelfBoundingAndCovariantArguments {
void testA(Setter s1, Setter s2, SelfBoundSetter sbs){
s1.set(s2);
//s1.set(sbs); //error
}
}
package CuriouslyRecurringGeneric;
public class SelfBoundingMethods {
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());
}
}
package CuriouslyRecurringGeneric;
class Other{}
class BasicOther extends BasicHolder<Other>{}
//不受限定的類
public class Unconstrained {
public static void main(String [] argv){
BasicOther b = new BasicOther(), b2 = new BasicOther();
b.set(new Other());
Other other = b.get();
b.f();
}
}