1

I't first time i've occourred in this "strange" situation. I need to create two different constructor for my class:

public OpponentListAdapter(Context c, ArrayList<MyCustomObject> l){}

and

public OpponentListAdapter(Context c, ArrayList<String> l){}

because depending by type of generics of ArrayList, i need to perform different actions. But i have this error:

Method OpponentListAdapter(Context, ArrayList) has the same erasure >OpponentListAdapter(Context, ArrayList) as another method in type OpponentListAdapter

What's wrong? Maybe the solution it's simple, but for now, i can't find nothing good!

giozh
  • 9,868
  • 30
  • 102
  • 183
  • it's not strange, it's the way generics work. The compiler removes the unbounded type and replace it with Object. So, from the compiler perspective, you have two constructors with the same signature – Blackbelt Feb 04 '14 at 15:55

3 Answers3

6

Both the ArrayList<String> and ArrayList<MyCustomObject> have same erasure ArrayList. Thus, both the constructors will have same signature at runtime, and hence that exception, as you have a duplicate constructor there.

If you want the constructor to take different types of ArrayList, then you can either use unbounded wildcard as in:

public OpponentListAdapter(Context c, ArrayList<?> l) {}

that will work for both the array lists, or make your constructor generic, giving a type parameter.

Rohit Jain
  • 209,639
  • 45
  • 409
  • 525
  • so, in this way inside constructor i need just to check if class of first list element is MyCustomObject.class or java.lang.String, then cast to correct type. Nice. – giozh Feb 04 '14 at 16:01
1

You have two constructors with the same signature, constructor1(Context, ArrayList), constructor2(Context, ArrayList), meaning the constructors are the same.

pedromss
  • 2,443
  • 18
  • 24
0

As an alternative, your OpponentListAdapter could have a public static "creator"-methods. This would look like this:

public class OpponentListAdapter {

  // A constructor is not necessary but you could have one if you want
  public OpponentListAdapter(Context c, ArrayList<String> l){
    ...
  }

  //now the creator method
  public static OpponentListAdapter create(Context c, ArrayList<MyCustomObject> l){
     // implement the creation here and return it
  }

}

This way you have still type safety. This pattern is used fairly often and names for the methods are usually something like:

  • create()
  • of() // popular example is List.of() from Java 9+
  • from()

In your case you could have e.g. 2 different static functions:

  • createFromString(Context c, List<String> l)
  • createFromMyCustomObject(Context c, List<MyCustomObject> l)

Calling it would look something like this:

...
  List<String> ls = ...
  List<MyCustomObject> lo = ...

  OpponentListAdapter adapterFromStrings = OpponentListAdapter.createFromStrings(c, ls);
  OpponentListAdapter adapterFromMyObject = OpponentListAdapter.createFromObjects(c, lo);
...
Younes El Ouarti
  • 2,200
  • 2
  • 20
  • 31