Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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;
   }

}
like image 990
AndyC Avatar asked Jul 15 '10 17:07

AndyC


People also ask

What is duplicate code in Java?

Simply put, it's when a snippet of code appears multiple times throughout a codebase. It happens for many reasons: Somebody wanted to reuse a function in a different class, and copy-paste was the quickest solution.

How do I stop Java repeating code?

To avoid the problem of duplicated bugs, never reuse code by copying and pasting existing code fragments. Instead, put it in a method if it is not already in one, so that you can call it the second time that you need it.

What causes compile error in Java?

Compile-time errors occur when there are syntactical issues present in application code, for example, missing semicolons or parentheses, misspelled keywords or usage of undeclared variables. These syntax errors are detected by the Java compiler at compile-time and an error message is displayed on the screen.

Is Java compiled twice?

Java code needs to be compiled twice in order to be executed: Java programs need to be compiled to bytecode. When the bytecode is run, it needs to be converted to machine code.


1 Answers

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.

like image 106
gtrak Avatar answered Sep 20 '22 21:09

gtrak