开发者

Feature or Bug:Why does this Java code compile? [duplicate]

This question already has answers here: Closed 12 years ago.

Possible Duplicate:

Is this valid Java?

I was surprised to discover the Java class below compiles. It has several method, with the same name, number of arguments and following type-erasure types of argument. Yet, it compiles and works as expected, on windows using various versions of the Sun JDK 1.6 compiler. So if this is a bug it has been around for ages....

It has also compiled with numerous versions of Eclipse, but does not compiler with the compiler that ships with Eclipse 3.6

In addition calling code works as expected - ie. there are no errors about ambigious methods on the calling code.

If you 开发者_运维技巧iterate over the methods returned by ErasureExample.class.getMethods() they are all present.....

According to the JLS it would be illegal if the methods have "override-equivalent" signatures - strictly they don't, as none of Collection, Collection nor Collection are override equivalent.... if that's the case the Eclipse is wrong, JDK correct...

Feature or bug? Should it compile?

/**
 * Demonstrates that a class with methods that differ only by return type can exist.
 * Section 8.4 of the JLS suggests this is an error IFF the methods had
 * override equivalent signatures, which they dont''
 *
 * 
 * From JLS 8.4...

 * It is a compile-time error for the body of a class to declare as members two methods 
 * with override-equivalent signatures (§8.4.2) (name, number of parameters, and types
 * of any parameters). 
 *
 * Should it compile?
 */
public class ErasureExample {
   // note the single Collection<Integer> argument...
   public static int[] asArray(Collection<Integer> vals) {
      if (vals == null)
         return null;

      int idx = 0;
      int[] arr = new int[vals.size()];
      for (Integer i : vals) {
         arr[idx] = i==null? 0 : i.intValue();
         idx++;
      }
      return arr;
   }

   // same method name as above, type differs only by generics.... surely this violates 8.4 of JLS...
   public static long[] asArray(Collection<Long> vals) {
      if (vals == null)
         return null;

      int idx = 0;
      long[] arr = new long[vals.size()];
      for (Long i : vals) {
         arr[idx] = i==null? 0 : i.longValue();
         idx++;
      }
      return arr;
   }

   // same method name as above, type differs only by generics.... surely this violates 8.4 of JLS...
   public static boolean[] asArray(Collection<Boolean> vals) {
      if (vals == null)
         return null;

      int idx = 0;
      boolean[] arr = new boolean[vals.size()];
      for (Boolean b : vals) {
         arr[idx] = b==null? false : b.booleanValue();
         idx++;
      }
      return arr;
   }

}


The compiler is smart enough to disambiguate the methods at compile-time, although in the end it performs type erasure. The whole point of parameterizing generics is to provide a compile-time type safety check, type erasure is just an implementation detail.


These methods do not have the same signatures at all. Different return values and different parameter types. Yes indeed, generics do make a big difference. Everything looks good here.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜