java class declaration <T> - java

I'm familiar with simple class declaration public class test but I don't understand public class test<T>.

< T > refers to a generic type.
Generic types are introduced in Java to provide you with compile time, and this is important due to type erasure, type-safety.
It's especially useful in Collections because it frees you from manual casting.
It is a good idea to read more on generics, especially the documentation on the topic by Angelika Langer is very good: http://www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.html

I assume that HTML ate your <T> (you need to write <T> to display it)
T is a type parameter or "generic" parameter. Say you have a List. Then it is for the structure of the list unimportant what exactly you are storing there. Could be Strings, Dates, Apples, SpaceShips, it doesn't matter for list operations like add, remove etc. So you keep it abstract when defining the class ("this is an abstract list"), but specify it when you instantiate it ("this is a list of Strings")
//in Java, C# etc would be similar
//definition
public class List<T> {
public void add(T t) { ... }
public void remove(T t) { ... }
public T get(int index) { ... }
}
//usage
List<String> list = new List<String>();
list.add("x"); //now it's clear that every T needs to be a String
...

You are probably referring to Java Generics:
http://www.oracle.com/technetwork/java/javase/generics-tutorial-159168.pdf

This is parametric polymorphism, another important form of polymorphism other than subtyping.
In Java land, they call it Generics (see also Lesson: Generics).

Related

any use case of declaring a List<?> [duplicate]

I am refreshing my knowledge on Java generics. So I turned to the excellent tutorial from Oracle ... and started to put together a presentation for my coworkers. I came across the section on wildcards in the tutorial that says:
Consider the following method, printList:
public static void printList(List<Object> list) {
...
The goal of printList is to print a list of any type, but it fails to achieve that goal — it prints only a list of Object instances; it cannot print List<Integer>, List<String>, List<Double>, and so on, because they are not subtypes of List<Object>. To write a generic printList method, use List<?>:
public static void printList(List<?> list) {
I understand that List<Object> will not work; but I changed the code to
static <E> void printObjects(List<E> list) {
for (E e : list) {
System.out.println(e.toString());
}
}
...
List<Object> objects = Arrays.<Object>asList("1", "two");
printObjects(objects);
List<Integer> integers = Arrays.asList(3, 4);
printObjects(integers);
And guess what; using List<E> I can print different types of Lists without any problem.
Long story short: at least the tutorial indicates that one needs the wildcard to solve this problem; but as shown, it can be solved this way too. So, what am I missing?!
(side note: tested with Java7; so maybe this was a problem with Java5, Java6; but on the other hand, Oracle seems to do a good job regarding updates of their tutorials)
Your approach of using a generic method is strictly more powerful than a version with wildcards, so yes, your approach is possible, too. However, the tutorial does not state that using a wildcard is the only possible solution, so the tutorial is also correct.
What you gain with the wildcard in comparison to the generic method: You have to write less and the interface is "cleaner" since a non generic method is easier to grasp.
Why the generic method is more powerful than the wildcard method: You give the parameter a name which you can reference. For example, consider a method that removes the first element of a list and adds it to the back of the list. With generic parameters, we can do the following:
static <T> boolean rotateOneElement(List<T> l){
return l.add(l.remove(0));
}
with a wildcard, this is not possible since l.remove(0) would return capture-1-of-?, but l.add would require capture-2-of-?. I.e., the compiler is not able to deduce that the result of remove is the same type that add expects. This is contrary to the first example where the compiler can deduce that both is the same type T. This code would not compile:
static boolean rotateOneElement(List<?> l){
return l.add(l.remove(0)); //ERROR!
}
So, what can you do if you want to have a rotateOneElement method with a wildcard, since it is easier to use than the generic solution? The answer is simple: Let the wildcard method call the generic one, then it works:
// Private implementation
private static <T> boolean rotateOneElementImpl(List<T> l){
return l.add(l.remove(0));
}
//Public interface
static void rotateOneElement(List<?> l){
rotateOneElementImpl(l);
}
The standard library uses this trick in a number of places. One of them is, IIRC, Collections.java
Technically, there is no difference between
<E> void printObjects(List<E> list) {
and
void printList(List<?> list) {
When you are declaring a type parameter, and using it only once, it essentially becomes a wildcard parameter.
On the other hand, if you use it more than once, the difference becomes significant. e.g.
<E> void printObjectsExceptOne(List<E> list, E object) {
is completely different than
void printObjects(List<?> list, Object object) {
You might see that first case enforces both types to be same. While there is no restriction in second case.
As a result, if you are going to use a type parameter only once, it does not even make sense to name it. That is why java architects invented so called wildcard arguments (most probably).
Wildcard parameters avoid unnecessary code bloat and make code more readable. If you need two, you have to fall back to regular syntax for type parameters.
Hope this helps.
Both solutions are effectively the same, it's just that in the second one you are naming the wildcard. This can come handy when you want to use the wildcard several times in the signature, but want to make sure that both refer to the same type:
static <E> void printObjects(List<E> list, PrintFormat<E> format) {

Are wildcard generics really needed?

for example:
public String add(Set<?> t){
...;
}
public <T> String add(Set<T> t){
...;
}
The first uses wildcard generics; the second is the normal form of a generic method.
What's the difference?
In what situation do we need wildcard generics, not the normal form of generics?
Here is a situation where wildcards are required. This method takes a List<List<?>>, which is a list of lists. The method can add lists of different component types into it:
public void foo(List<List<?>> t) {
t.add(new ArrayList<String>());
t.add(new ArrayList<Integer>());
}
You cannot do this using generic type parameters without wildcards. For example, the following does not work:
public <T> void foo(List<List<T>> t) {
t.add(new ArrayList<String>()); // does not compile
t.add(new ArrayList<Integer>()); // does not compile
}
Since support for generics was added, using a parameterized type without providing a type parameter usually causes a compiler warning. On the other hand, there are situations where you don't care at all what the type parameter is (i.e. you don't use the type anywhere) or, even worse, you might not know what T is at all, and using <?> lets you express just that without causing a compiler warning.
Possible use case for the "don't care" case (very simple for brevity, but you get the idea):
public void clearList(List<?> list) {
list.clear();
}
An example for the "don't know" case: an actual method signature from Class class:
static Class<?> forName(String className);
Here the method returns an object of some Class type. Class is generic but of course you don't know the type because it depends on the className parameter which is resolved at runtime. So you can't put T here since T is not known at compile time (even for a particular call site), and using just Class without type parameter would be a bad practice and cause a compiler warning.
The wildcard form is when you don't mind what types of objects you are handling.
The generics form allows you to add contraints on the type of objects handled.
An example use case could be the following :
a generic repository with add/update/remove methods, you define common behavior using the generic type :
public class Repository<T>{
public void add(T t){...}
public void update(T t){...}
public void remove(T t){...}
}
Then to make a repository for Apple and Banana you just extend this class and replace T with the real type :
public class AppleRepo extends Repository<Apple> {}
public class BananaRepo extends Repository<Banana> {}
If the generic Repository was declared as Repository<?>, it would not be good because it is not restricted to Banana, and you would not be able to use Banana specific methods inside it without casting objects;
Also the generics allow you to express further constraints, for example
Repository<T extends Fruit>
allows you to restrict the generic repository class to fruits. And you will be able to make calls to Fruit methods in its code.
There's not difference in calling the methods.
In the second method (add(Set<T>)) you can create variables of type T:
public <T> String add(Set<T> t){
T item = t.iterator().next();
//....
}
That gives you some additional type checking.
In the first method you're left with using Object.

Demand `T extends Comparable<T>` only for certain methods

I'm trying to write a generic class in Java. A few methods in that class require that T extends Comparable<T>. How can I make it such that T is required to be comparable only if one of those methods is used? Or maybe there's some other way I should organize my class?
Here's the class I'm trying to implement. Its and array that I plan to use on both comparable and non-comparable types.
// I know Java has its own containers, but this
// is homework and I'm not allowed to use them
class Array<T>
{
// Some methods that pose no
// special restrictions on T
// These require that T be comparable
public Array<T> union(...) {...}
public Array<T> intersect(...) {...}
}
You can hide type T for method. T of Test is not the same as T of CompareMethodhere.
public static class Test<T> {
<T extends Comparable<T>> void compareMethod(T t, Class<T> classt) {
}
void normalMethod(T t) {
}
}
Now example
Test<String> test = new Test<String>();//Comparable class
test.compareMethod("",String.class);//works fine
Test<Random> tes1t = new Test<Random>();//Non Comparable class
tes1t.compareMethod(new Random(),Random.class);//Compilation error here
tes1t.normalMethod(new Random());//Works fine
new Test<Random>().compareMethod("",String.class);// Not a good but can be valid
new Test<String>().compareMethod(new Random(),Random.class);//Compilation error here
Update:
After being cursed about this solution I did some search in java API and this practice gets followed for toArray() method
ArrayList<String> string = new ArrayList<String>();
string.toArray(new Integer[5]);<--Illegal however <T> is hide by toArray method
Edit: It looks like this is possible after all (see AmitD's post). But anyway, other possible solutions are
Refactor the methods requiring comparable into a subclass
Just use casts in the relevant methods, meaning that that part will only be checked at runtime.
It wont be possible through normal method such as using comparable.
It would be better if you share what is the exact requirement.
If Sorting in ArrayList/Arrays are your goal, then Comparing Non Comparable classes is useless. Sorting can only be done in objects of the same or sub types.
But if you are going to use compare for checking if the objects are equal or not then I'll suggest that you override equals(Object O) method.

Java Generics - explanation needed

I have a question about Java Generics. In code below we have interface B parametrized by another type that must implement interface A.
This code is correct.
Question is: why it does not work with following list() method declaration?
private <X extends A, Y extends B<X>> List<Y> list()
Working code:
public interface A {
}
public interface B<T extends A> {
}
public class Test {
private static class AA implements A {}
private static class BB implements B<AA> {}
private <R extends A, X extends R, Y extends B<X>> List<Y> list() {
return null;
}
private void test() {
List<BB> l = list();
}
}
EDIT:
I've reworked the code. Now we have bird paremetrized by sound it can make. Question is why useless_t is necessary?
public class Test {
public interface Sound {
}
public interface Bird<T extends Sound> {
}
private static class Quack implements Sound {}
private static class Duck implements Bird<Quack> {}
private <useless_t extends Sound, sound_t extends useless_t, bird_t extends Bird<sound_t>> List<bird_t> list() {
return null;
}
private void test() {
List<Duck> l = list();
}
}
My Eclipse IDE does not compile any of your code examples as is. But they do compile when given additional type hints. In the second example, with or without the type parameter useless_t, the following line does not compile for me:
List<Duck> l = list();
But the following does compile for me:
List<Duck> l = this.<Sound, Quack, Duck> list();
With the useless_t factored out, the following compiles, too:
List<Duck> l = this.<Quack, Duck> list();
So it is basically a matter of the compiler not getting the type parameters right, and you need to give the types explicitly.
UPDATE : If you really came across a program where adding the useless_t made a difference, you are on unsafe terrain, and rely on unspecified compiler behaviour.
You ran into an issue where different compilers behave differently, namely Type Inference. The JLS is not entirely clear on where a compiler must infer types, and where it must refuse to infer, so there is wiggle room here. Different versions of the Eclipse compiler and different versions of javac differ in where they do infer types. For javac, this is true even when comparing different 1.5.0_x versions, and the Eclipse compiler usually can infer more than javac.
You should only rely on type inference where all common compilers succeed, and otherwise give type hints. Sometimes, that is as easy as introducing a temporary variable, but sometimes (as in your example) you must use the var.<Types>method() syntax.
Regarding the comment: what if i want method Duck.getSound() to return Quack, not Sound using generics?
Assume the Bird interface had the following method:
public interface Bird<T extends Sound> {
T getSound();
}
Then you could implement it like so:
private static class Duck implements Bird<Quack> {
public Quack getSound() { return new Quack(); }
}
This is one use case for generics - allow implementations to specify concrete types, so that even the superclass can use that type. (The Bird interface could have a setSound(T), or do other stuff with T, without knowing the concrete type of T.)
If a caller only knew that an instance was of type Bird<? extends Sound>, he would have to call getSound like so:
Sound birdSound = bird.getSound();
If the caller knew about Quack, he could perform an instanceof test. But if the caller knew that the bird was really a Bird<Quack>, or even that is was a Duck, then he can write this and it compiles as desired:
Quack birdSound = bird.getSound();
But beware: Generifying too many types used in the interface or superclass brings the risk of overcomplicating the system. As Slanec wrote, Rethink your real design to see whether it's really needed to have so many generics.
I once went too far, and ended up with a interface hierarchy and two implementation hierarchies, based on interfaces like this:
interface Tree<N extends Node<N>,
T extends Tree<N, T>> { ... }
interface SearchableTree<N extends SearchableNode<N>,
S extends Searcher<N>,
T extends SearchableTree<N, S, T>>
extends Tree<N, T> { ... }
I do not recommend to follow that example. ;-)
I'd say: AA implements A, by defining List<AA> l = list() you expect it to extend B<X> which it does not. Anyway, you see how easly you get confused by writing such code. This is just TOO complex.
You have a slight misunderstanding of Java Generics. The thing to remember, and this is a subtle thing, a List<Y> is not about the contents of the list, but a modification of the list itself.
Let's extrapolate a little bit; say I have interface Animal and interface Dog extends Animal and interface Cat extends Animal. (I'll just invent more classes and interfaces as we go along.) Now if I declare a method that returns animals as List<Animal> createList(), there's nothing wrong with the following code:
List<Animal> litter = createList();
Cat tabby = new Tabby();
litter.add(tabby);
Dog poodle = new Poodle();
litter.add(poodle);
That's because a Dog is an Animal, and a Cat is an Animal; the method signature of add on type List<Animal> is add(Animal); we can call add with any valid instance of Animal, as expected. But the type parameter on List does not modify or restrict the contents of the list, it modifies the type of the list itself; and a "list of cats" is not a "list of animals", neither is a "list of dogs". Even if the createLitter() method actually returns a new ArrayList<Animal>() that contains only instances of Parrot, the above code is fine. What you cannot do however is 'narrow' the type of the list. For example, this is a compile error:
List<Bird> birds = createList(); // does not compile
Imagine if it were allowed, and createList returned a "list of animals" that contained our tabby; the following would result in a class cast exception:
Bird leaderOfTheFlock = birds.get(0);
You also cannot 'widen' the type of list. Imagine if it were possible:
List<Object> things = createList(); // does not compile
The reason this is not allowed either is that code could now add a new Integer(0) to things - because an Integer is an Object. Clearly that's not what we want either, and for the same reason - a "list of animals" is not a "list of objects". The type parameter "Animal" on List<Animal> modifies the type of the list itself, and we are talking about two distinct types of lists. This leads us to the first consequence of that point - generic types do not follow the inheritance (is-a) hierarchy.
Without knowing more of what you want to do it's hard to go from here and stay relevant. I don't mean to be harsh, but it looks like you started throwing generics at your code to see if something would work. I struggled for years with Generics. Even after running across a blog that explained this subtle point I had to recreate quite a few variations of the above to reinforce the lesson, looking for various ways I would end up with a class-cast-exception if I broke the rules. Likely the solution to your problem is that other parts of the code are not well defined with respect to the strict type system you are trying to introduce, and the generics problems you see are only a symptom of that. Try to reduce the generics and rely more on composition and inheritance. I still shoot myself in the foot occasionally by going off the generic deep end. It's also helpful to try and remember the point of generics is not to eliminate casts, but to make type information available to the compiler as an aid to verifying the correctness of how your code deals with the types; or in other words it turns runtime errors (class cast) into source / compile-time errors, so it is important to try to keep in mind the distinction between what type information you have at compile-time (which is limited, even with generics) and what type information you have at runtime (which is the full type information of the instances).

Java : What is - public static<T> foo() {...}?

I saw a java function that looked something like this-
public static<T> foo() {...}
I know what generics are but can someone explain the in this context? Who decides what T is equal to? Whats going on here?
EDIT: Can someone please show me an example of a function like this.
You've missed the return type out, but apart from that it's a generic method. As with generic types, T stands in for any reference type (within bounds if given).
For methods, generic parameters are typically inferred by the compiler. In certain situations you might want to specify the generic arguments yourself, using a slightly peculiar syntax:
List<String> strings = Collections.<String>emptyList();
In this case, the compiler could have inferred the type, but it's not always obvious whether the compiler can or can't. Note, the <> is after the dot. For syntactical reasons the type name or target object must always be specified.
It's possible to have generic constructors, but I've never seen one in the wild and the syntax gets worse.
I believe C++ and C# syntaxes place the generic types after the method/function name.
The context is a generic method as opposed to a class. The variable <T> applies only to the call of the method.. The Collections class has a number of these; the class itself is not generic, but many of the methods are.
The compiler decides what T is equal to -- it equals whatever gets the types to work. Sometimes this is easier then others.
For example, the method static <T> Set<T> Collections.singleton(T o) the type is defined in the parameter:
Collections.singleton(String T)
will return a Set<String>.
Sometimes the type is hard to define. For example sometimes there is not easily enough information to type Collection.emptyList(). In that case you can specify the type directly: Collection.<String>emptyList().
T it's the formal type parameter wich will be replaced by the actual type
argument used at the instantiation of the object.
For example, here is the List and Iterator definitios in package java.util:
public interface List<E>{
void add(E x);
Iterator<E> iterator();
}
public interface Iterator<E>{
E next();
boolean hasNext();
}
Then you can instantiate a List this way:
List<String> ls = new ArrayList<String>()
Where you might imagine that List stands for a version of List where E has
been uniformly replaced by String:
public interface StringList{
void add(String x)
Iterator<String> iterator();
}

Categories

Resources