import java.lang.Override; import java.util.*; class GenericsTest { static S next(GenericsTest test) { System.out.println(test); return null; } public Iterator iterator() { return new Iterator() { @Override public boolean hasNext() { return false; } @Override public T next() { return GenericsTest.next(GenericsTest.this); } @Override public void remove() { } }; } } class GenericsTest1 { static S next1(GenericsTest1 test) { System.out.println(test); return null; } public Iterator iterator() { return new Iterator() { @Override public boolean hasNext() { return false; } @Override public T next() { return GenericsTest1.next1(GenericsTest1.this); } @Override public void remove() { } }; } } class GenericsTest2 { static S next2(GenericsTest2 test) { System.out.println(test); return null; } public Iterator iterator() { return new Iterator() { @Override public boolean hasNext() { return false; } @Override public T next() { return next2(GenericsTest2.this); } @Override public void remove() { } }; } } class Example { private static void assertThat(T actual, Matcher matcher) { assert actual != null; assert matcher != null; } private static Matcher> hasSize(int size) { assert size >=0; return new Matcher>() { @Override public void foo(Collection es) { System.out.println(es); } }; } public static void main(String[] args) { List list = new ArrayList(); System.out.println(list); assertThat(new ArrayList(), hasSize(0)); } private interface Matcher { void foo(T t); } } abstract class IDEA57337<S> { abstract void foo(IDEA57337> x); void bar(IDEA57337> x){ foo(x); } }