bxb100 / bxb100.github.io

This is my blog
https://blog.tomcat.run
MIT License
1 stars 0 forks source link

Java generics with overloading #20

Open bxb100 opened 1 year ago

bxb100 commented 1 year ago

The scenario:

    public static void test1(Object... args) {

    }

    public static void test1(List<Object> args) {

    }

there are two overloading method, but when you're using

  List<Long> list1 = new ArrayList<>();
  test1(list1);

It's always using the first method test1(Object... args), but when using List<Object> list2 the executor is different, It's too wired


Some document identified

The example above shows why generics and arrays don't mix well together. An array is what is called reifiable type -- a type where full type information is available during run-time. It is because Java array is reifiable that the Java run-time can check what we store into the array matches the type of the array and throw an ArrayStoreException at us if there is a mismatch. Java generics, however, is not reifiable due to type erasure. Java designers have decided not to mix the two.^1

the List<?> means you can assign any type of List to it and List<Object> means you can store any type of object into it.^2

Sure, it's not the same question, but I think some conception can go to the same destination

I think the runtime compiler design to obey this:

  1. List same as List<Object>
  2. List<Type> list1 with generics can accept any type
  3. List<Object> means just accept List<Object> or List
  4. List<T> list1 calling varargs method equals new Object[]{ list1 }
  5. Using test1(Collections.singletonList(x)) equals test1(new ArrayList<Object>())

So this is the check trick problem

bxb100 commented 1 year ago

generics safety term like PECS

bxb100 commented 1 year ago
public static void test1(List<Object> args) {

}

Diff with

public static void test1(List args) {

}
public static void test1(List<?> args) {

}