2

While working on my project in android, I came across this weird problem (probably that's my lack of understanding generics in java) related to method overloading. I defined the following static methods in a utility class and it gave me error.

public static void getAllFromDatabase(Context context, ArrayList<Student> students) {
    DatabaseHelper dh = new DatabaseHelper(context);
    students = dh.getStudents();
    dh.close();
}

public static void getAllFromDatabase(Context context, ArrayList<LogEntry> logs) {
    DatabaseHelper dh = new DatabaseHelper(context);
    logs = dh.getlog();
    dh.close();
}

Any help? Thanks in advance.

Sher Alam
  • 362
  • 2
  • 9
  • 1
    what errors ? you got – M D Dec 29 '15 at 06:31
  • Erasure of method getAllFromDatabase(Context, ArrayList) is the same as another method in type CommonUtilities – Sher Alam Dec 29 '15 at 06:32
  • **With a counterpart** Erasure of method getAllFromDatabase(Context, ArrayList) is the same as another method in type CommonUtilities – Sher Alam Dec 29 '15 at 06:33
  • 2
    Generics are erased, meaning, the information about the generic type exists only during compilation time - during runtime both methods have the same erasure-type which in fact is not overloading but compilation error for the same signature. – Nir Alfasi Dec 29 '15 at 06:34
  • 1
    These methods won't work anyway - you cannot return a value by assigning to a parameter – Thomas Kläger Dec 29 '15 at 06:43
  • 1
    And that's just because they are both `static` methods? @ThomasKläger – Sher Alam Dec 29 '15 at 08:36
  • What did you mean by "you cannot return a value by assigning to a parameter" ? @ThomasKläger – Sher Alam Dec 29 '15 at 08:53
  • 1
    `students = dh.getStudents();` updates the parameter `students`. This assignment is lost after the method ends. You should `return students;`. And no, this is not specific to static methods. See http://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value – Thomas Kläger Dec 29 '15 at 08:59
  • Exactly. `dh.getStudents()` creates another reference, which is assigned to the local variable of the method, and that original reference gets lost inside method. Its like `students = new Arraylist();` Thank you so much. – Sher Alam Dec 29 '15 at 09:21

5 Answers5

0

Remember to put the type parameter in the class definition.

public class CustomCallBack<T> implements Callback {

    public void getAllFromDatabase(Context context, ArrayList<T> logs) {
    }
}

You could reference it on https://docs.oracle.com/javase/tutorial/java/generics/types.html

Chris Yu
  • 39
  • 2
0

Due to the type erasure process,you are encountering this issue because both method are same after that.

From Doc

During the type erasure process, the Java compiler erases all type parameters and replaces each with its first bound if the type parameter is bounded, or Object if the type parameter is unbounded.

See Java generics - type erasure - when and what happens

Community
  • 1
  • 1
Prince
  • 2,577
  • 2
  • 12
  • 31
0

This is because of When Java implemented generics, to make the bytecode backwards compatible, java erases the type to make signature as generic, at runtime generic information is gone and the signature will look as :

public static void getAllFromDatabase(Context context, ArrayList students);
public static void getAllFromDatabase(Context context, ArrayList logs); 

So you have two methods with same type of arguments, therefore you will get an error. Try more with; http://docs.oracle.com/javase/tutorial/java/generics/erasure.html

Sandeep Kokate
  • 797
  • 3
  • 15
0

It is presumably because of erasure; if Java had generics from the start this might not have happened. You might see the two parameters as different type, but when the <> is removed the JVM will see two methods with Map as the type of their parameters.

You can cheat though, by giving the methods a different return type. Although after erasure they both have the same name and parameters, it will be different in byte code because the entire signature is not the same - the return type is different

Mohammad Salem
  • 953
  • 7
  • 15
  • My two methods are static. Changing the return type removes the error, but I wonder which one of them will get called if i make a call like `CommonUtilities.getAllFromDatabase(context, logList)` remember that `logList` uses ``. – Sher Alam Dec 29 '15 at 08:34
0

You are getting error because of Type Erasure. Type Erasure removes all generics information at compile time.

Method resolution occurs at compile time and doesn't consider type parameters.

Java generics uses type erasure. The bit in the angle brackets <Student> and <LogEntry> gets removed, so you'd end up with two methods that have an identical signature . That's not allowed because the runtime wouldn't know which to use for each case.

Rajesh
  • 12,393
  • 4
  • 47
  • 76