There are methods like these which require Class literals as argument.
Collection<EmpInfo> emps =
SomeSqlUtil.select(
EmpInfo.class,
"select * from emps");
or
GWT.create(Razmataz.class);
The problem presents itself when I need to supply generic specific classes like
EmpInfo<String>
Razmataz<Integer>
The following would be wrong syntax
Collection<EmpInfo<String>> emps =
SomeSqlUtil.select(
EmpInfo<String>.class,
"select * from emps");
or
GWT.create(Razmataz<Integer>.class);
Because you cannot do syntax like
Razmataz<Integer>.class
So, how would I be able to squeeze a class literal out of
EmpInfo<String>
Razmataz<Integer>
so that I could feed them as arguments to methods requiring Class literals?
Further info
Okay, I confess that I am asking this primarily for GWT.
I have a pair of GWT RPC interface Razmataz. (FYI, GWT RPC interface has to be defined in server-client pairs). I plan to use the same interface pair for communicating whether it be String, Integer, Boolean, etc.
GWT.create(Razmataz) for Razmataz<T>
complains that, since I did not specify T, GWT compiler treated it as Object. Then GWT compiler would not accept Object class. It needs to be more specific than being an Object.
So, it seems there is no way for me to tell GWT.create what T is because a Class literal is a runtime concept while generics is a compile time concept, Right?
Quote from Java Generics and Collections, section 7.2:
Class literals are also restricted; it is not even syntactically valid to supply a type parameter to the type in a class literal. Thus, the following fragment is illegal:
class ClassLiteral {
public Class<?> k = List<Integer>.class; // syntax error
}
Indeed, Java's grammar makes a phrase such as the preceding one difficult to parse, and it may trigger a cascade of syntax errors [...]
This syntax problem leads to an irregularity. Everywhere else that a reifiable type is required, you may supply either a raw type (such as List) or a parameterized type with unbounded wildcards (such as List<?>). However, for class tokens, you must supply a raw type; not even unbounded wildcards may appear. Replacing List<Integer> with List<?> in the preceding code leads to a similar error cascade.
So, you have no choice but use only raw types in class tokens, like
GWT.create(Razmataz.class);
You can't.
Use an unsafe cast:
Collection<EmpInfo<String>> emps =
(Collection<EmpInfo<String>>) someMethod(EmpInfo.class);
Someone left a short but concise answer here, which I was about to choose as the answer. Unfortunately, that person deleted that answer. If that person would be so kind to re-post that answer for me to select. In the mean time, let me state that answer and how I made use of it.
This is what I should have thought of,
Interface RazmatazString extends Razmataz<String>{}
GWT.create(RazmatazString.class);
Basing on the answer that was deleted,
I would have a basic Razmataz interface pair the does a lot of stuffs, which I am too lazy to repeat.
Abstract class Razmatazer{
.....
Interface Razmataz<T>{
// does a lot of RPC stuffs
}
Interface RazmatazAsync<T>{
// does a lot of RPC stuffs
}
RazmatazAsync<?> razmatazAsyncRPC;
}
The concept is not to instantiate razmatazAsyncRPC handle at the base class but at the derived class.
For T = String
StringRazmatazer extends Razmatazer{
Interface RazmatazStringAsync extends RazmatazAsync<String>{}
Interface RazmatazString extends Razmataz<String>{}
razmatazAsyncRPC = GWT.create(RazmatazString.class);
}
Otherwise I would have to repeat ~100 lines of code, ~50 each for Razmataz and RazmatazAsync, over various T parametric values of String, Map, Boolean, Integer, etc.
The basic premise for overcoming this hurdle was - I am lazy to repeat those lines.
Related
I have the following function:
/**
* Finds all entities of a certain type
* #param <T> The type of the entity
* #param entityType The class of the entity
* #return A list of all the entities found, null if the entity is not in the database
* or on error
*/
public <T> List<T> findAll(Class entityType)
{
javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
cq.select(cq.from(entityType));
return getEntityManager().createQuery(cq).getResultList();
}
You will note it is rather repetitive. Is there anyway that I can refactor this function so that it does not need to take a Class as a parameter. Is there anyway that I can use the generic type being passed in?
No, you cannot — directly. In a couple paragraphs I'll show you another way around the problem.
Java generics are implemented via type erasure, meaning that all type information is stripped away at runtime. When your method is invoked, it knows that it is supposed to return a List, but at run time there is nothing to tell it that it is supposed to return List<Foo>. The ArrayList constructor doesn't need access to the class object to do its job; your code, however, does.
The way around this is to just pass the class which, since this is a generic method (as opposed to a generic class), you can do. If you change the declaration of your method to be
public <T> List<T> findAll(Class<T> entityType)
Then you can call it with the class:
findAll(String.class)
and the compiler will automatically detect that it is supposed to return a List<String>. It reduces the redundancy, but by inferring the type argument from the class rather than the other way around. This is the standard way to solve this kind of problem — it shows up a lot in libraries like Guava.
The standard practice to create a "Generic DAO" is to have an abstract class that is parametrizable and have subclasses with a specific parameter. This way, the method itself is already parametrized with the correct type.
Take a look at this for an example:
http://netbeans.org/projects/samples/sources/samples-source-code/content/samples/javaee/AffableBean/src/java/session/AbstractFacade.java
Not really, no. Generics are a compile time feature. At run time a caller of your API can supply any instance of Class<T> for entityType so you need it available at runtime to provide to hibernate. The compiler has no ability to basically build a separate version of the method for every possible T, which is what it would have to do in order to omit the class parameter.
Also, Class is a raw type, you are already using generics improperly ;)
Java uses Type erasure, which means that the generic type parameter is not available at runtime (used at compile time to ensure your code is correct wrt to types). This means that to use persistence you will need to explicitly pass the class so the runtime can figure out how to do the persistence (e.g. what class the persisted object belongs to)
The simple answer is "no". Due to something called type erasure, all parameterized types are treated as Object.class at runtime in the compiled bytecode. The generic types are only used at compile time to prevent you from using things wrong.
You can more or less do what you're asking in Scala. (I'm not sure if you can use scala, but just for reference, here it is).
object Main extends App{
def findAll[T : Manifest]() : Array[T] = {
var a = new Array[T](0)
println(a.getClass)
a
}
var result = findAll[String]()
println(result.getClass)
var result2 = findAll[Array[Int]]()
println(result2.getClass)
}
By using the implicit Manfiest, the scala compiler keeps a record of what generics get erased on compile.
I am frequently pushing the limits of Java's type system through my use of Guice, TypeLiteral, generics, and wildcards. I often run into situations where I need to perform unchecked casts, which pretty much ruins type safety--in other words, "Generics Hell."
Here's a simplified example of some of my problematic Java code.
class SquareDrawer implements ShapeDrawer<Row<Square>> {}
class Client {
Key<SquareDrawer> SQUARE_DRAWER_KEY =
Key.get(SquareDrawer.class, randomAnnotation());
void bindShapeDrawer(
Key<? extends ShapeDrawer<Row<? extends Shape>>> shapeDrawer) {}
Client() {
// Note Unchecked cast required below
bindShapeDrawer(
(Key<? extends ShapeDrawer<Row<? extends Shape>>>) SQUARE_DRAWER_KEY);
}
}
I've been learning Scala and have been under the impression (or illusion) that it has better support for generics than Java. Could the above code be written in Scala to avoid the unchecked casts?
Is there still a need for Guice's TypeLiteral in Scala?
There are a couple of things Scala offers.
Higher kinded types (I hope I use the term correctly) allow you to define things like 'any type having another type as a type parameter' afaik there is no way to express that in java
Co and Contravariant type parameters. In java you can make parameters one or the other by using wildcards in every place where they are used. In Scala you just declare them as such.
Type witnesses (Again: Is that the correct term?) are implicit functions that demonstrate some property of type arguments, thereby defining constraints on the type. If an implicit conversion matching the declaration of the witness exists, the call will compile the condition holds.
Path dependent types. You can have types that are elements of instances, so each instance has its own type. Again you can't do this in java afaik.
Scala has a form of reified types called Manifests. They let you do things that would be quite clunky in Java due to type erasure. Read all about them here: http://www.scala-blogs.org/2008/10/manifests-reified-types.html
The following (hopefully) equivalent Scala code compiles without errors. Maybe I need to state that it contains no dynamic casts. Note that I had to make Key covariant in its type argument, because SquareDrawer is only a subtype of ShapeDrawer[Row[Square]].
trait ShapeDrawer[A]
trait Row[A]
trait Shape
trait Square extends Shape
trait Key[+A]
//your code starts here
trait SquareDrawer extends ShapeDrawer[Row[Square]]
class Client{
val SDK = new Key[SquareDrawer]{}
bindShapeDrawer(SDK)
def bindShapeDrawer[SD[A] <: ShapeDrawer[A],S <: Shape](shapeDrawer: Key[SD[Row[S]]]) {}
}
I just saw this C# question and wondered, if something similar could happen in Java. It can, with
class A<T> {
A(Integer o) {...}
A(T o) {...}
}
the call
new A<Integer>(43);
is ambiguous and I see no way how to resolve it. Is there any?
You can drop the generics during construction (and suppress a warning):
A<Integer> a = new A(42);
or, less preferably use reflection (where again you'd have to suppress warnings)
Constructor<A> c = A.class.getDeclaredConstructor(Integer.class);
A<Integer> a = c.newInstance(42);
Yes, members of a parameterized type JLS3#4.5.2 can end up in conflicts that are precluded in a normal class declaration(#8.4.8). It's pretty easy to come up with many examples of this kind.
And in Java, neither constructor in your example is more specific than the other, because there is no subtyping relation between T and Integer. see also Reference is ambiguous with generics
If method overloading creates this kind of ambiguity, we can usually choose to use distinct method names. But constructors cannot be renamed.
More sophistries:
If <T extends Integer>, then indeed T is a subtype of Integer, then the 2nd constructor is more specific than the 1st one, and the 2nd one would be chosen.
Actually javac wouldn't allow these two constructors to co-exist. There is nothing in the current Java language specification that forbids them, but a limitation in the bytecode forces javac to forbid them. see Type Erasure and Overloading in Java: Why does this work?
Another point: If <T extends Integer>, since Integer is final, T can only be Integer, so Integer must also be a subtype of T, therefore isn't the 2nd constructor also more specific than the 1st?
No. final isn't considered in subtyping relations. It is actually possible to drop final from Integer one day, and Java even specifies that removing final does not break binary compatibility.
Indeed, it is ambiguous, and so doesn't compile if you try new A<Integer>(new Integer(0)).
I have the following problem:
Given a Guice type literal TypeLiteral<T> template and a class Class c implementing or extending T, construct a type Type t which is equivalent to c with all type variables instantiated so as to be compatible with template.
If c has no type variables, it's easy; c is the type in question. However, if c has type variables, then I need to do the following:
Find the type in c's inheritance and implementation hierarchy corresponding to the raw type of T
Walk through the type parameter structure, finding any type variable uses and their corresponding types in template
Use the Guice Types helper functions to create a type from c instantiated with the types found in (2).
Of course, there are error cases and it might not be complete. If it can't find matching uses of all type variables, it will fail. There might be other cases as well. However, if I have this:
class CS<I> implements S<Map<I,Float>> {
// some stuff
}
and a type literal TypeLiteral<S<Map<I,Float>>>, I want to get a type which represents CS fully instantiated to match the type literal.
It looks like reflection provides enough information to accomplish this, but the logic looks complex and error-prone. Is there an existing library which exposes this logic?
TypeLiteral.getSupertype() should do the trick:
TypeLiteral<?> t = TypeLiteral.get(x).getSupertype(y);
This problem is an instance of the unification problem, and as such the standard unification algorithm is applicable and not as complicated as I initially thought. Further, this instance of the problem allows for some significant simplifying assumptions, as one of the trees will contain no variables. 200 lines of Java later, I have a working solution.
this morning I came across this code, and I have absolutely no idea what that means. Can anyone explain me what do these <T> represent? For example:
public class MyClass<T>
...
some bits of code then
private Something<T> so;
private OtherThing<T> to;
private Class<T> c;
Thank you
You have bumped into "generics". They are explained very nicely in this guide.
In short, they allow you to specify what type that a storage-class, such as a List or Set contains. If you write Set<String>, you have stated that this set must only contain Strings, and will get a compilation error if you try to put something else in there:
Set<String> stringSet = new HashSet<String>();
stringSet.add("hello"); //ok.
stringSet.add(3);
^^^^^^^^^^^ //does not compile
Furthermore, another useful example of what generics can do is that they allow you to more closely specify an abstract class:
public abstract class AbstClass<T extends Variable> {
In this way, the extending classes does not have to extend Variable, but they need to extend a class that extends Variable.
Accordingly, a method that handles an AbstClass can be defined like this:
public void doThing(AbstClass<?> abstExtension) {
where ? is a wildcard that means "all classes that extend AbstClass with some Variable".
What you see here is something called Generics. They were introduced to Java in release 1.5.
You can read about them here and here. Hope this helps.
Imagine you're writing a List or Array class. This class must be able to hold elements of an unknown type. How do you do that?
Generics answers this question. Those <T> you're seeing can be read as some type. With generics you can write class MyList<T> { ... }, which in this context means a list that holds some type.
As an usage example, declare a list to store integers, MyList<Integer> listOfInts, or strings, MyList<String> listOfStrings, or one class you've written yourself MyList<MyClass> listOfMyClass.
What you are seeing is Java generics, which allows classes and methods to be parameterized by other classes. This is especially useful when creating container classes, since it saves you having to create separate classes for "a list of integers", "a list of strings", etc. Instead, you can have a single "list of some type T, where T is a variable" and then you can instantiate the list for some specific type T. Note that Java generics is not quite the same as template types in C++; Java generics actually use the same class definition but add implicit casting (generated by the compiler) and add additional type-checking. However, the different instantiations actually make use of the same exact type (this is known as erasure), where the parameterized types are replaced with Object. You can read more about this at the link.
Since noone has mentioned it yet, there is a very comprehensive guide/FAQ/tutorial on generics which can be found on Angelika Langer's site.