This is implemented as follows (jdk1.6.0_31):
private static class ReverseComparator<T>
implements Comparator<Comparable<Object>>, Serializable {
// use serialVersionUID from JDK 1.2.2 for interoperability
private static final long serialVersionUID = 7207038068494060240L;
public int compare(Comparable<Object> c1, Comparable<Object> c2) {
return c2.compareTo(c1);
}
private Object readResolve() { return reverseOrder(); }
}
Why can't it instead be implemented as follows:
private static class ReverseComparator<T extends Comparable<T>>
implements Comparator<T>, Serializable {
// use serialVersionUID from JDK 1.2.2 for interoperability
private static final long serialVersionUID = 7207038068494060240L;
public int compare(T c1, T c2){
return c2.compareTo(c1);
}
...
}
Is it just style, or is there some deeper reason?
EDIT: the source code shown is from Sun/Oracle jdk ((jdk1.6.0_31)).
I believe it is all related to the intention of making of ReverseComparator a singlenton object. Since the singlenton instance has to be defined in a static context there is no point in using any generic types.
static final ReverseComparator REVERSE_ORDER = new ReverseComparator();
This code, generates a raw type warning.
As such, the implementation of ReverseComparator, which is only used for this matter, could have been as you suggested or as it was implemented. Perhaps they chose the current implementation because it is easier to read, and because they thought that further generalization was not needed if it was only going to be privately used for this simple purpose.
Running the Java decompiler over your implementation and over the Oracle's implementation produces the same raw type byte codes.
public int compare(java.lang.Comparable, java.lang.Comparable
public int compare(java.lang.Object, java.lang.Object);
At the end, when the comparator is exposed through the public interface of the Collections class in the reverseOrder() method, it is impossible to avoid the casting and the unchecked warning. But we all are sure that this cannot fail, regardless of types involved.
Bottom line, IMHO I think the only reason why it was implemented as it was has to do with code clarity, or with the desire of not complicating the things more than necessary if, anyways, the unchecked warning could not be prevented. But hey, this wouldn't be the first time I am wrong ;-)
Just guessing, but it's stored in a static field
static final ReverseComparator REVERSE_ORDER
= new ReverseComparator();
so your version would generate a 'raw types' warning.
I'm looking at Oracle 1.6.0_26, but I see the same code. As far as I can tell, those are functionally equivalent. You could also potentially write it like this:
private static class ReverseComparator<T> implements Comparator<Comparable<T>>, Serializable {
// use serialVersionUID from JDK 1.2.2 for interoperability
private static final long serialVersionUID = 7207038068494060240L;
public int compare( Comparable<T> c1, Comparable<T> c2 ) {
return c2.compareTo( (T) c1 );
}
private Object readResolve() {
return reverseOrder();
}
}
My only guess as to why they did it using Comparable<Object> is based on the fact that classes that implement Comparable (or Comparator) should obey the equals()contract, which does use Object. So semantically, this emphasizes that connection. Other than that, I can't think of a reason why.
Related
I'm trying to define a container for a whole bunch of classes as some parts of the code will make more sense with a collection but other places will make sense with single values.
Ideally I'd like to do this:
public class AllModes<T> {
private T<Car> car;
private T<Boat> boat;
private T<Train> train;
private T<Plane> plane;
...40 more of these...
}
then I'd like to use the class like:
AllModes<List> allModes;
AllModes<Optional> oneOfEachMode;
But I get the error I get is "The type T is not generic; it cannot be parameterized with arguments "
The reason I'm defining these in multiple variables and not a single HashSet based on a superclass is I want to have get methods that return the correct types to avoid consumers of this class needing to cast down everywhere as each object has its own distinct fields.
I also considered just storing a single value list or set but I thought it might less error prone to use the correct type I intended (ie. one value)
You can't achieve what you want using the Java type system.
Since you can't have a generic container type, you'll need to enforce the invariants with dedicated constructors (or subclasses).
But if you do so, the clients of your class will not be able to distinguish between different container types (Optional vs List), they will need to work with a generic abstraction (like Stream, Iterator, Iterable, whatever suits you).
Here's an example:
public class AllModes {
private final Supplier<Stream<Car>> cars;
private final Supplier<Stream<Boat>> boats;
public AllModes(Optional<Car> car, Optional<Boat> boat) {
// Assuming Java 8, when Optional did not have a stream() method yet
this.cars = () -> car.map(Stream::of).orElse(Stream.empty());
this.boats = () -> boat.map(Stream::of).orElse(Stream.empty());
}
public AllModes(List<Car> cars, List<Boat> boats) {
this.cars = cars::stream;
this.boats = boats::stream;
}
public Stream<Car> getCars() {
return cars.get();
}
public Stream<Boat> getBoats() {
return boats.get();
}
}
You can't solve it this way. Use the instanceof operator instead. Here is an example:
public class AllModes<T> {
private T object;
private void check(T object) {
if(object instanceof Boat){
System.out.println("Boat");
// your code for Boat goes here
} else if (object instanceof Car) {
System.out.println("Car");
// your code for Car goes here
}
}
}
I'd suggest you take a step back and re-consider what exactly you want to achieve with this container. E.g. ask yourself what its domain is or what the client is supposed to do with Allmodes<T>...
Another more concrete question that comes to mind is how exactly you intend to popuplate that Optional<T> generically? Will it be the first element in the List<T> or the last? Or an element which satisfies a specific Predicate<T>?
Your design doesn't seem to be that well thought out yet.
What you could do which would come close to what you descibed (in case I got that right) is provide an accessor of type Stream<T> as you could get both a List<T> aswell as an Optional<T> from it. Your client would then have to make that decision and also determine how exactly to derive the Optional<T> from the Stream<T>.
From The Java™ Tutorials - Why Use Generics?:
By using generics, programmers can implement generic algorithms that work on collections of different types, can be customized, and are type safe and easier to read.
You can have multiple types in class and then you can associated them with the fields. But in your case, you have several fields with some type. A class don't have much dependencies on others. You should design you class in a way that there are no much dependencies there.
public class AllModes<T,T1,T2,T3> {
private T car;
private T1 boat;
private T2 train;
private T3 plane;
}
G'day, I was aiming to create an abstract (base) class by extend-ing EnumMap. I already have existing prototype code that works great based on an EnumMap sub-class and I want to convert that into a generic base that I can use with different Enum-types (i.e. generic Enum<K>).
The road-block I struck is ...
How to tell the EnumMap constructor the class of the generic Enum<K>?
For comparison the working (non-generic) class look like the following, given the Enum<States>:
public class MyMap extends EnumMap<States, FocusTraversalPolicy>
{
private static States DEFAULT_POLICY;
private static States currentPolicy = DEFAULT_FLOW;
public MyMap (){
this( States.DATA_INPUT );
}
public MyMap ( final ProcessState defaultPolicy ){
super(States.class );
DEFAULT_POLICY = defaultPolicy;
currentPolicy = DEFAULT_FLOW;
}
}
My ability to translate this into a generic version has hit a set of alternative errors which boils down to a difficulty passing the Enum type (K.class) to the EnumMap's parent constructor, viz.
Cannot select from type variable
and (briefly)
No suitable constructor found ...
argument mismatch; Class<CAP#1> cannot be converted to Class<K>)
My declaration so far looks like this:
public abstract class MapBase<K> extends EnumMap<K, FocusTraversalPolicy>{
private K DEFAULT_POLICY;
private K currentPolicy;
private Enum Dummy {
NOTHING
}
private MapBase() { // disable empty constructor
this(Dummy.NOTHING); // Exclude NullPointerException-s
}
public MapBase( final K defaultPolicy ) // Default compulsory
{
super( K.class ); // <-- Cannot select from type variable
// OR
super( defaultPolicy.getClass() ); // <-- No suitable constructor found
DEFAULT_POLICY = defaultPolicy;
currentPolicy = DEFAULT_FLOW;
}
}
This is as far as I got. I attempted a few variations with more or less different ways to tell me the same thing, e.g.
class MapBase<K extends Enum<K>>
extends EnumMap<K, FocusTraversalPolicy>{
:
}
While a generics version for the base class is the Most desirable, it seems that this may not be possible; or that I am not following the right syntax to making the 'kind of' base-class I want.
Even knowing if, "You can't do that." Is helpful and I'll divert my efforts to a different structure. It just seems more OO to inherit versus re-inventing a perfectly good existing prototype wheel. My thanks in advance.
The glaring problem with the code is the apparent inappropriate use of inheritance. You're unlikely to save much memory, and the code becomes a mess.
So the start of the class becomes
public class TraversalPolicies<K extends Enum<K>> {
private final Map<K, FocusTraversalPolicy> policies;
The constructor for EnumMap needs the Class of the enum because it is going to do something funky indexing the ordinal into an array of values.
The straightforward was of doing this is having the Class object passed to your generic class.
public TraversalPolicies(Class<K> clazz) {
this.policies = new EnumMap<>(clazz);
Alternatively, the Class can be taken from an instance of the enum if you have one available.
public TraversalPolicies(K defaultPolicy) {
this.policies = new EnumMap<>(defaultPolicy.getDeclaringClass());
I'm a .NET guy, so let me first assert my understanding of a few Java concepts - correct me if I'm wrong.
Java Generics support the concept of bounded wildcards:
class GenericClass< ? extends IInterface> { ... }
...which is similar to the .NET where restriction:
class GenericClass<T> where T: IInterface { ... }
Java's Class class describes a type, and is roughly equivalent to .NET Type class
So far, so good. But I can't find a close enough equivalence to the Java genericly typed Class<T> where T is a bounded wildcard. This basically imposes a restriction on the types that the Class represents.
Let me give an example in Java.
String custSortclassName = GetClassName(); //only known at runtime,
// e.g. it can come from a config file
Class<? extends IExternalSort> customClass
= Class.forName("MyExternalSort")
.asSubclass(IExternalSort.class); //this checks for correctness
IExternalSort impl = customClass.newInstance(); //look ma', no casting!
The closest I could get in .NET is something like this:
String custSortclassName = GetClassName(); //only known at runtime,
// e.g. it can come from a config file
Assembly assy = GetAssembly(); //unimportant
Type customClass = assy.GetType(custSortclassName);
if(!customClass.IsSubclassOf(typeof(IExternalSort))){
throw new InvalidOperationException(...);
}
IExternalSort impl = (IExternalSort)Activator.CreateInstance(customClass);
The Java version looks cleaner to me.
Is there a way to improve the .NET counterpart ?
Using extension methods & a custom wrapper class for System.Type, you can get pretty close to the Java syntax.
NOTE: Type.IsSubclassOf cannot be used to test if a type implements an interface - see the linked documentation on MSDN. One can use Type.IsAssignableFrom instead - see the code below.
using System;
class Type<T>
{
readonly Type type;
public Type(Type type)
{
// Check for the subtyping relation
if (!typeof(T).IsAssignableFrom(type))
throw new ArgumentException("The passed type must be a subtype of " + typeof(T).Name, "type");
this.type = type;
}
public Type UnderlyingType
{
get { return this.type; }
}
}
static class TypeExtensions
{
public static Type<T> AsSubclass<T>(this System.Type type)
{
return new Type<T>(type);
}
}
// This class can be expanded if needed
static class TypeWrapperExtensions
{
public static T CreateInstance<T>(this Type<T> type)
{
return (T)Activator.CreateInstance(type.UnderlyingType);
}
}
Further improvements using interface variance
(Should only be used in production code after the performance has been evaluated. Could be improved by using a (concurrent!) cache dictionary ConcurrentDictionary<System.Type, IType<object>)
Using Covariant type parameters, a feature introduced with C# 4.0, and an additional type interface IType<out T>, which Type<T> implements, one could make things like the following possible:
// IExternalSortExtended is a fictional interface derived from IExternalSort
IType<IExternalSortExtended> extendedSort = ...
IType<IExternalSort> externalSort = extendedSort; // No casting here, too.
One could even do:
using System;
interface IType<out T>
{
Type UnderlyingType { get; }
}
static class TypeExtensions
{
private class Type<T> : IType<T>
{
public Type UnderlyingType
{
get { return typeof(T); }
}
}
public static IType<T> AsSubclass<T>(this System.Type type)
{
return (IType<T>)Activator.CreateInstance(
typeof(Type<>).MakeGenericType(type)
);
}
}
static class TypeWrapperExtensions
{
public static T CreateInstance<T>(this IType<T> type)
{
return (T)Activator.CreateInstance(type.UnderlyingType);
}
}
So that one can (explicitly) cast between unrelated interfaces InterfaceA and InterfaceB like:
var x = typeof(ConcreteAB).AsSubclass<InterfaceA>();
var y = (IType<InterfaceB>)x;
but that kinda defeats the purpose of the exercise.
C# generics is declaration-site variance, the variance of a type parameter is fixed.
Java is use-site variance, so once we have a declaration List<E>, we can use it 3 ways
List<Number> // invariant, read/write
List<+Number> // covariant, read only
List<-NUmber> // contravariant, write only
There are pros and cons to both approaches. The use-site approach is apparently more powerful, though it gained the reputation as being too difficult to programmers. I think it is actually pretty easy to grasp
List<Integer> integers = ...;
List<+Number> numbers = integers; // covariant
Unfortunately, Java invented an absolutely hideous syntax,
List<? extends Number> // i.e. List<+Number>
once your code has several of these it becomes really ugly. You have to learn to get over it.
Now, in the declaration-site camp, how do we achieve 3 variances on the same class? By having more types - a ReadOnlyList<out E>, a WriteOnlyList<in E>, and a List<E> extending both. This is not too bad, and one might say it's a better design. But it may become ugly if there are more type parameters. And if the designer of a class did not anticipate it being used variantly, the users of the class have no way to use it variantly.
You can get a slightly prettier version using the "as" operator:
String custSortclassName = GetClassName();
Assembly assy = GetAssembly();
Type customClass = assy.GetType(custSortclassName);
IExternalSort impl = Activator.CreateInstance(customClass) as IExternalSort;
if(impl==null) throw new InvalidOperationException(...);
But here I'm creating the instance before checking its type, which may be an issue for you.
You can try writing an extension method like the following:
static class TypeExtension
{
public static I NewInstanceOf<I>(this Type t)
where I: class
{
I instance = Activator.CreateInstance(t) as I;
if (instance == null)
throw new InvalidOperationException();
return instance;
}
}
Which can then be used in the following manner:
String custSortclassName = GetClassName(); //only known at runtime,
// e.g. it can come from a config file
Assembly assy = GetAssembly();
Type customClass = assy.GetType(custSortclassName);
IExternalSort impl = customClass.NewInstanceOf<IExternalSort>();
Suppose I'm trying to write a function to return an instance of the current type. Is there a way to make T refer to the exact subtype (so T should refer to B in class B)?
class A {
<T extends A> foo();
}
class B extends A {
#Override
T foo();
}
To build on StriplingWarrior's answer, I think the following pattern would be necessary (this is a recipe for a hierarchical fluent builder API).
SOLUTION
First, a base abstract class (or interface) that lays out the contract for returning the runtime type of an instance extending the class:
/**
* #param <SELF> The runtime type of the implementor.
*/
abstract class SelfTyped<SELF extends SelfTyped<SELF>> {
/**
* #return This instance.
*/
abstract SELF self();
}
All intermediate extending classes must be abstract and maintain the recursive type parameter SELF:
public abstract class MyBaseClass<SELF extends MyBaseClass<SELF>>
extends SelfTyped<SELF> {
MyBaseClass() { }
public SELF baseMethod() {
//logic
return self();
}
}
Further derived classes can follow in the same manner. But, none of these classes can be used directly as types of variables without resorting to rawtypes or wildcards (which defeats the purpose of the pattern). For example (if MyClass wasn't abstract):
//wrong: raw type warning
MyBaseClass mbc = new MyBaseClass().baseMethod();
//wrong: type argument is not within the bounds of SELF
MyBaseClass<MyBaseClass> mbc2 = new MyBaseClass<MyBaseClass>().baseMethod();
//wrong: no way to correctly declare the type, as its parameter is recursive!
MyBaseClass<MyBaseClass<MyBaseClass>> mbc3 =
new MyBaseClass<MyBaseClass<MyBaseClass>>().baseMethod();
This is the reason I refer to these classes as "intermediate", and it's why they should all be marked abstract. In order to close the loop and make use of the pattern, "leaf" classes are necessary, which resolve the inherited type parameter SELF with its own type and implement self(). They should also be marked final to avoid breaking the contract:
public final class MyLeafClass extends MyBaseClass<MyLeafClass> {
#Override
MyLeafClass self() {
return this;
}
public MyLeafClass leafMethod() {
//logic
return self(); //could also just return this
}
}
Such classes make the pattern usable:
MyLeafClass mlc = new MyLeafClass().baseMethod().leafMethod();
AnotherLeafClass alc = new AnotherLeafClass().baseMethod().anotherLeafMethod();
The value here being that method calls can be chained up and down the class hierarchy while keeping the same specific return type.
DISCLAIMER
The above is an implementation of the curiously recurring template pattern in Java. This pattern is not inherently safe and should be reserved for the inner workings of one's internal API only. The reason is that there is no guarantee the type parameter SELF in the above examples will actually be resolved to the correct runtime type. For example:
public final class EvilLeafClass extends MyBaseClass<AnotherLeafClass> {
#Override
AnotherLeafClass self() {
return getSomeOtherInstanceFromWhoKnowsWhere();
}
}
This example exposes two holes in the pattern:
EvilLeafClass can "lie" and substitute any other type extending MyBaseClass for SELF.
Independent of that, there's no guarantee self() will actually return this, which may or may not be an issue, depending on the use of state in the base logic.
For these reasons, this pattern has great potential to be misused or abused. To prevent that, allow none of the classes involved to be publicly extended - notice my use of the package-private constructor in MyBaseClass, which replaces the implicit public constructor:
MyBaseClass() { }
If possible, keep self() package-private too, so it doesn't add noise and confusion to the public API. Unfortunately this is only possible if SelfTyped is an abstract class, since interface methods are implicitly public.
As zhong.j.yu points out in the comments, the bound on SELF might simply be removed, since it ultimately fails to ensure the "self type":
abstract class SelfTyped<SELF> {
abstract SELF self();
}
Yu advises to rely only on the contract, and avoid any confusion or false sense of security that comes from the unintuitive recursive bound. Personally, I prefer to leave the bound since SELF extends SelfTyped<SELF> represents the closest possible expression of the self type in Java. But Yu's opinion definitely lines up with the precedent set by Comparable.
CONCLUSION
This is a worthy pattern that allows for fluent and expressive calls to your builder API. I've used it a handful of times in serious work, most notably to write a custom query builder framework, which allowed call sites like this:
List<Foo> foos = QueryBuilder.make(context, Foo.class)
.where()
.equals(DBPaths.from_Foo().to_FooParent().endAt_FooParentId(), parentId)
.or()
.lessThanOrEqual(DBPaths.from_Foo().endAt_StartDate(), now)
.isNull(DBPaths.from_Foo().endAt_PublishedDate())
.or()
.greaterThan(DBPaths.from_Foo().endAt_EndDate(), now)
.endOr()
.or()
.isNull(DBPaths.from_Foo().endAt_EndDate())
.endOr()
.endOr()
.or()
.lessThanOrEqual(DBPaths.from_Foo().endAt_EndDate(), now)
.isNull(DBPaths.from_Foo().endAt_ExpiredDate())
.endOr()
.endWhere()
.havingEvery()
.equals(DBPaths.from_Foo().to_FooChild().endAt_FooChildId(), childId)
.endHaving()
.orderBy(DBPaths.from_Foo().endAt_ExpiredDate(), true)
.limit(50)
.offset(5)
.getResults();
The key point being that QueryBuilder wasn't just a flat implementation, but the "leaf" extending from a complex hierarchy of builder classes. The same pattern was used for the helpers like Where, Having, Or, etc. all of which needed to share significant code.
However, you shouldn't lose sight of the fact that all this only amounts to syntactic sugar in the end. Some experienced programmers take a hard stance against the CRT pattern, or at least are skeptical of the its benefits weighed against the added complexity. Their concerns are legitimate.
Bottom-line, take a hard look at whether it's really necessary before implementing it - and if you do, don't make it publicly extendable.
You should be able to do this using the recursive generic definition style that Java uses for enums:
class A<T extends A<T>> {
T foo();
}
class B extends A<B> {
#Override
B foo();
}
I may not fully understood the question, but isn't it enough to just do this (notice casting to T):
private static class BodyBuilder<T extends BodyBuilder> {
private final int height;
private final String skinColor;
//default fields
private float bodyFat = 15;
private int weight = 60;
public BodyBuilder(int height, String color) {
this.height = height;
this.skinColor = color;
}
public T setBodyFat(float bodyFat) {
this.bodyFat = bodyFat;
return (T) this;
}
public T setWeight(int weight) {
this.weight = weight;
return (T) this;
}
public Body build() {
Body body = new Body();
body.height = height;
body.skinColor = skinColor;
body.bodyFat = bodyFat;
body.weight = weight;
return body;
}
}
then subclasses won't have to use overriding or covariance of types to make mother class methods return reference to them...
public class PersonBodyBuilder extends BodyBuilder<PersonBodyBuilder> {
public PersonBodyBuilder(int height, String color) {
super(height, color);
}
}
Just write:
class A {
A foo() { ... }
}
class B extends A {
#Override
B foo() { ... }
}
assuming you're using Java 1.5+ (covariant return types).
If you want something akin to Scala's
trait T {
def foo() : this.type
}
then no, this is not possible in Java. You should also note that there is not much you can return from a similarly typed function in Scala, apart from this.
I found a way do this, it's sort of silly but it works:
In the top level class (A):
protected final <T> T a(T type) {
return type
}
Assuming C extends B and B extends A.
Invoking:
C c = new C();
//Any order is fine and you have compile time safety and IDE assistance.
c.setA("a").a(c).setB("b").a(c).setC("c");
Why the order of declaration important for Java enums, I mean why does this give (compile time) errors
public enum ErrorCodes {
public int id;
Undefined;
}
but this one is fine:
public enum ErrorCodes {
Undefined;
public int id;
}.
It's not a very satisfying answer, but it's just how enums are defined in Java. See section 8.9 Enums in The Java Language Specification.
Because this is the syntax for enums. It could allow different orders however this may have been open to mistakes such as forgetting to place a type on a field and turning it into a enum value.
EDIT: The reason I say they could be in any order is that fields, methods, initialisers and constructors can be in any order. I believe the restriction is valid if it is to reduce mistakes. Even though fields/constructors/methods can be in any order its very common to see them in that order for readability.
Java Enum is a special kind of class. Its simple and mostly useful form does not contain custom fields:
public enum ErrorCodes {
Undefined, Defined, Foo, Bar
}
Compiler magic creates class that looks approximately like the following:
public class ErrorCodes {
public final static ErrorCodes Undefined = new ErrorCodes();
public final static ErrorCodes Defined = new ErrorCodes();
public final static ErrorCodes Foo = new ErrorCodes();
public final static ErrorCodes Bar = new ErrorCodes();
}
This compiler magic expects the fields definition right after the enum header.
Sun were so kind to allow us to add such fields that follow the definition of eunum members:
public enum ErrorCodes {
Undefined, Defined, Foo, Bar;
private String myField;
}
This is the reason that your custom code always must be defined after the enum fields.