This question already has answers here:
Method has the same erasure as another method in type
(8 answers)
Closed 1 year ago.
Here is the code:
public class Test {
private static void print(List<Plant> plants) {
}
private static void print(List<Animal> animals) {
}
}
class Animal {
}
class Plant {
}
When I want to overload print method in Test class for Animal and Plant lists, the compiler says that "both methods have same erasure". When I research "method erasure", I could not relate it to my situation.
Because both List<Plant> and List<Animal> are List (raw type) using type erasure, so compiler sees 2 print methods are identical.
Related
This question already has answers here:
What is the concept of erasure in generics in Java?
(7 answers)
Closed 2 years ago.
I have a customized object including fields:
private List<Duration> durations;
private Duration single;
When debugging, I evaluate the following expression and the result is java.lang.String which is different from the declared type. Why?
durations.get(0).getClass()
As a comparison, the class of single is Duration, same as declared type.
If any help, I got the data deserialized from MySQL.
getClass gives you the runtime class of the Object.
Here is a short example:
import java.util.ArrayList;
import java.util.List;
class T {
String sam = "jack";
public String getSam() {return sam;}
public void setSam(String sam) {this.sam = sam;}
}
public class Test {
public static void main(String[] args) {
List<T> list = new ArrayList<T>();
T t = new T();
list.add(t);
Class<? extends T> c = list.get(0).getClass();
System.out.println(list.get(0).getSam().getClass());
}
}
Which means you can't operate normal operations on the variable as you do when you initialize a class variable with the keyword new.
So, t.getSam() is possible whereas c.getSam() is invalid.
If you need further clarification, then provide the full class Duration and what objective that you are looking for.
This question already has answers here:
Is List<Dog> a subclass of List<Animal>? Why are Java generics not implicitly polymorphic?
(19 answers)
Closed 3 years ago.
Why this is not allowed?
error: incompatible types: List<TextBook> cannot be
converted to List<Book>
process(textBooks);
import java.util.*;
class Book {}
class TextBook extends Book {}
public class Sample {
public static void process(List<Book> books) {}
public static void main(String[] args) {
List<Book> books = new ArrayList<>();
process(books);
System.out.println(“OK”)
List<TextBook> textBooks = new ArrayList<>();
process(textBooks); # what is the problem in this statement?
System.out.println(“OK”);
}
}
You are trying to pass a List<TextBook> into a method whose signature expects a List<Book>. This fails at compile time, because if the Java compiler were to allow it, then your process() method might try to use the contents of the list in the wrong way. Instead, use this version of process():
public static void process(List<? extends Book> books) {}
Now you may pass in any instance of Book, or any subclass of Book.
This is not allowed because you started out with an arraylist of Textbook. However you passed it to process as a list of Book. The process function could add something which is not a textbook to the list. At this point your original list would not be an arraylist of Textbook.
This question already has answers here:
Java erasure with generic overloading (not overriding)
(3 answers)
Closed 3 years ago.
I wanted to know if it is possible to overload a method by differing in the generic parameter. Example:
class Foo <T> { ... }
class Bar {
public void do (Foo<Integer> obj) {}
public void do (Foo<Double> obj) {}
}
I know this will not be compiled. But for example in kotlin you have the annotation JvmName where you can annotate these methods to get compiled the code. Do Java has this possibility, too?
You cannot have two methods with the same erasure in the same type. That said, you may be able to manipulate the erasure retaining the same type. For instance, if Foo was an interface:
interface Foo<T> { /* ... */ }
class Bar {
public void do_(Foo<Integer> obj) { }
public <A extends Object & Foo<Double>> void do_(A obj) { }
}
But, avoid overloading methods even where generics are not involved.
This question already has answers here:
What is a raw type and why shouldn't we use it?
(16 answers)
Closed 4 years ago.
Here is a pathological generics example in Java. What is going on here?
public abstract class Foo<X> {
private List<String> stuff;
public List<String> getStuff() {
return stuff;
}
public void setStuff(List<String> stuff) {
this.stuff = stuff;
}
}
Then I created a subclass, but not I did not specify the type bound, which should make it object.
public class Bar extends Foo {
public Bar() {
setStuff(new ArrayList<>());
}
public void whatIsGoingOnHere() {
for(String thing : getStuff())
System.out.println("Why is this a compiler error???");
}
}
Why is this a compiler error?
You call setStuff(new ArrayList<>());. Here ArrayList<> isn't not bound, it is inferred by the compiler if it can. And it can as setStuff is setStuff(List<String>). So the compiler knows it is a ArrayList<String> and uses (infers) that.
Your loop iterates over an List<String> as returned by the getStuff() method, so defining the thing as a String (or any super class or interface) will be okay for the compiler.
The base class does have an X type, but it doesn't matter as your stuff list is declared with a type. Only if you would define stuff as an List<X> it would matter what the subclass defined for X.
This question already has answers here:
Is List<Dog> a subclass of List<Animal>? Why are Java generics not implicitly polymorphic?
(19 answers)
Closed 7 years ago.
Why does Java not support automatic up-casting for template argument types?
For example, the following class will not compile unless the newly created Derived instance will be manually casted to a Base instance:
public class Example implements Iterable<Base> {
#Override
public Iterator<Base> iterator() {
return Arrays.asList(new Derived()).iterator();
}
private class Base {
}
private class Derived extends Base {
}
}
No need to cast.
The problem here is that Arrays.asList(new Derived()) naturally tries to create a List<Derived>,
and then calling .iterator() on a List<Derived> naturally gives an Iterator<Derived>,
which is not a sub-type of Iterator<Base>, so you get a compilation error.
You can specify that you want a List<Derived>, using Arrays.<Base>asList.
This works,
because you can certainly put a Derived instance into a List<Base>,
and then calling .iterator() on a List<Base> naturally gives an Iterator<Base>.
class Example implements Iterable<Base> {
#Override
public Iterator<Base> iterator() {
return Arrays.<Base>asList(new Derived()).iterator();
}
}