I was reading about Set interface from here which the code sipped below which is a generic method that removes duplicates from a collection.
My question is what is that **< E>** placed after static before Set<E> ?
I mean wouldn't that Set<E> be enough ? why <E> was there twice?
public static <E> Set<E> removeDups(Collection<E> c) {
return new LinkedHashSet<E>(c);
}
Here **<E>** is a generic type. Generic type is defined as
A generic type is a generic class or interface that is parameterized
over types. The following Box class will be modified to demonstrate
the concept. LINK
And regarding you question related to <E>. A good description for it can be found on the same tutorial
Type Parameter Naming Conventions
By convention, type parameter names are single, uppercase letters.
This stands in sharp contrast to the variable naming conventions that
you already know about, and with good reason: Without this convention,
it would be difficult to tell the difference between a type variable
and an ordinary class or interface name.
The most commonly used type parameter names are:
E - Element (used extensively by the Java Collections Framework)
K - Key
N - Number
T - Type
V - Value
S,U,V etc. - 2nd, 3rd, 4th types
You'll see these names used throughout the Java SE API and the rest of
this lesson.
This means that this method declares a generic parameter type which the class does not define; in this case, you MUST declare the parameter type before the return type (even if this "return type" is void).
Think about it this way. Remove the initial <E>. Your declaration would then become:
public static Set<E> removeDups(Collection<E> c)
What is E here? Unless it is a generic parameter type defined by the class itself, it can only be an existing class.
Hence this syntax. It allows you to define a generic parameter for use in the method signature.
It's just the generic type used within the method. Static methods that use generic types must specify that type before the return type.
Related
I was reading and reviewing the following site and had a question.
https://www.geeksforgeeks.org/angle-bracket-in-java-with-examples/
In the explanations below they show class definitions followed by <T> and then when actually implementing these classes they use different types such as or as the parameters. My question is: is the '' notation actually a defined syntax in Java? In particular, is the T a necessary thing in order to define a "Generic"? And then does it basically mean that the parameters can be of multiple different types? Also, if anyone can reword or explain in simpler terms what the meaning of a generic is that would be very helpful. Thanks.
The <T> is indeed a syntax defined by Java, but you can use whatever name you want to name a type, you don't need to use T, for example this is valid:
public class Box<MyType> {
private MyType t;
public void set(MyType t) { this.t = t; }
public MyType get() { return t; }
}
But, stick with T or other common type names, as other people are already used to seeing those as the "generic types" so it makes reading your code simpler.
I recommend you read Java's Trail about Generics, where you can find the most commonly used type parameter names:
E - Element
K - Key
N - Number
T - Type
V - Value
S,U,V etc. - 2nd, 3rd, 4th types
As for "what the meaning of generics is", check this other page.
It’s defined syntax since Java 5. You need a type parameter (one or more) for defining a generic. The type parameter needs not be called T, any Java identifier will do. A single uppercase letter is conventional, and T for type is what we often pick if we haven’t got a specific reason for some other letter.
The actual type parameter has to be a reference type. Values still always go into actual parameters in round brackets, not into type parameters (unlike in C++, for example). You can make a new ArrayList<Integer>(50), a list of Integer objects with an initial capacity for 50 of them.
That the actual type parameter has to be a reference type means that you can have a List<String>, a List<LocalDate> or a list of an interface type that you have declared yourself, even a List<int[]>. In the Java versions I have used (up to Java 10) the type parameter cannot be a primitive type (like int), but it can be an array type (like int[] or String[][], though often impractical). Allowing primitive types may come in a future Java version.
Link: Similar question: What does < T > (angle brackets) mean in Java?
From https://stackoverflow.com/a/31876747
In Java generics, a generic type definition is transformed to essentially one concrete generic type shared across all allowed type argument combinations. Thus, multiple (source code level) types are mapped to one (binary level) type - but as a result, information about the type arguments of an instance is discarded in that instance (type erasure).
Type information that could have been available at runtime (using reflection) is lost. This, in turn, means that specialization of a generic type (the ability to use specialized source code for any particular generic argument combination) is very restricted.
What are the consequences of "Type information that could have been available at runtime (using reflection) is lost"?
What does it means by "specialization of a generic type (the ability to use specialized source code for any particular generic argument combination) is very restricted"?
Maybe some examples?
Thanks.
I will start with a simple example called GenericTest. This class tries to find the type of parameters used in the ArrayList.
public class GenericTest {
// Result would be the same if I have used wildcard (?) instead,
// public static void findType(ArrayList<?> list)
public static void findType(ArrayList list) {
System.out.println(Arrays.toString(
list.getClass().getTypeParameters()));
}
public static void main(String[] args) {
findType(new ArrayList<Integer>());
findType(new ArrayList<String>());
}
}
Based on natural instinct, we expect the output to be:
[Integer]
[String]
Instead, we get the identifiers that are used as the parameter placeholders.
[E]
[E]
So in Java, you don't know the actual type parameter(s) used to create a particular instance of ArrayList. This is because Java generics are implemented using erasure.
This means the specific type information is erased from a generic. The only thing you know for sure is that you are using an object.
This is quite different from C++'s template world.
There are a few more differences but I will not get in here.
What does the first part in the following method definition?
<I, O> MyReturnType<I, O> myMethod() { ... }
The second is the method'sreturn type, third is the method name, but what is the first one?
I and O are declared as generic type parameters. They're generic types introduced by the method itself, as said here: https://docs.oracle.com/javase/tutorial/java/generics/methods.html
Generic methods are methods that introduce their own type parameters. This is similar to declaring a generic type, but the type parameter's scope is limited to the method where it is declared. Static and non-static generic methods are allowed, as well as generic class constructors.
If you don't declare <I, O>, java will look for types called I and O (which won't be there, since they're supposed to be generic).
I think #khelwood put it nicely (see comments on original question): It's saying: "In the following definition, I and O are standing in for some types that depend on the situation when the method is called."
I came across this code:
public class RestfulAdage extends Application {
#Override
public Set<Class<?>> getClasses() {
Set<Class<?>> set = new HashSet<Class<?>>();
set.add(Adages.class);
return set;
}
}
I do not understand what Class<?> means.
Class<?> refers to a class of unknown type. The notation uses an unbounded generic which places no restriction on the type of class that can be added to the Collection. For example the following would not work
Set<Class<String>> set = new HashSet<Class<String>>();
set.add(Adages.class); // type not allowed
Class is a parametrizable class, hence you can use the syntax Class where T is a type. By writing Class, you're declaring a Class object which can be of any type (? is a wildcard). The Class type is a type that contains metainformation about a class.
It's always good practice to refer to a generic type by specifying his specific type, by using Class you're respecting this practice (you're aware of Class to be parametrizable) but you're not restricting your parameter to have a specific type.
Reference about Generics and Wildcards: http://docs.oracle.com/javase/tutorial/java/generics/wildcards.html
Reference about Class object and reflection the (feature of Java language used to introspect itself): http://java.sun.com/developer/technicalArticles/ALT/Reflection/
In generic code, the question mark (?), called the wildcard, represents an unknown type. The wildcard can be used in a variety of situations: as the type of a parameter, field, or local variable; sometimes as a return type (though it is better programming practice to be more specific). The wildcard is never used as a type argument for a generic method invocation, a generic class instance creation, or a supertype.
The following sections discuss wildcards in more detail, including upper bounded wildcards, lower bounded wildcards, and wildcard capture.
for more information click here
It refers to gererics. I suggest you read a little on it. Basically, you know only at runtime what type of object you get to work with. For example, Class can be Integer, String or even YourDefinedClassType
read here http://java.sun.com/developer/technicalArticles/J2SE/generics/
From : Wildcards
In generic code, the question mark (?), called the wildcard, represents an unknown type. The wildcard can be used in a variety of situations: as the type of a parameter, field, or local variable; sometimes as a return type (though it is better programming practice to be more specific). The wildcard is never used as a type argument for a generic method invocation, a generic class instance creation, or a supertype.
Check the link, you will find more exhaustive documentation, examples etc.
Assume that you have a set of classes that belong to different types, and you have instances of different classes as well. So if you want to check whether these instances are instanceof one of these classes, you could iterate through these set and do the job. And for that kind of job, you better use a totally unrestricted set:
public boolean checkClasses(Set<Class<?>> typeLessClassSet, Set instances){
while(typeLessClassSet.hasNext()){
Class c = typeLessClassSet.next();
while(instances.hasNext()){
Object o = instances.next();
if(o instanceof c)
return true;
}
}
return false;
}
During my question I refer to the Java Language Specification in the third edition. According to the specification of the intersection type (§ 4.9) the intersection type int[] (or int[] & int[]) would have the same members as a class type with an empty body and the direct superclass int[]. But the way I understand the specification, a class type may not have an array type as an super type, because §8 tells:
Each class except Object is an extension of (that is, a subclass of) a single existing class (§8.1.4) and may implement interfaces (§8.1.5).
Do I understand something wrongly or is it an inconsistency in the specification?