GenericImpl implements Generic { @Override public Type asType() { if (lowerBound == null || "?".equals(lowerBound)) { if (upperBounds.isEmpty()) { throw new UnsupportedOperationException( "This generic has neither lower or upper bound, so it " + "can't be parsed into a Type."); } else if (upperBounds.size() > 1) { throw new UnsupportedOperationException( "Since no lowerBound is specified, this Generic needs " + "exactly one upper bound for a Type to be parsed. " + "Instead, it has " + upperBounds); } else { return upperBounds.get(0); } } return SimpleType.create(lowerBound); } GenericImpl();  GenericImpl(String lowerBound);  GenericImpl(Type... upperBounds);  GenericImpl(String lowerBound, Type... upperBounds); protected  GenericImpl(Generic prototype); @Override Generic setLowerBound(String lowerBound); @Override Optional<String> getLowerBound(); @Override Generic setBoundType(BoundType type); @Override BoundType getBoundType(); @Override List<Type> getUpperBounds(); @Override Type asType(); @Override GenericImpl copy(); @Override int hashCode(); @Override boolean equals(Object obj);  }
@Test void asType() { instance().setLowerBound("T"); instance().add(Integer.class); instance().add(List.class); final Type type = instance().asType(); assertTrue(type.getTypeName().contains("T")); }