Ambiguous constructor due to type erasure

185 Views Asked by At

I have a fragment of legacy source code which looks like this:

import javax.management.MBeanParameterInfo;
import javax.management.openmbean.OpenMBeanParameterInfoSupport;
import javax.management.openmbean.OpenType;

class C {
    void f() {
        final MBeanParameterInfo parameter = ...;
        final OpenType openType = ...;
        new OpenMBeanParameterInfoSupport("...", "...", openType, parameter.getDescriptor());
    }
}

The OpenMBeanParameterInfoSupport constructor used in the code was introduced in 1.6. Whenever the code is compiled with any 1.6+ javac, I receive the following error message:

reference to OpenMBeanParameterInfoSupport is ambiguous, both method OpenMBeanParameterInfoSupport(java.lang.String,java.lang.String,javax.management.openmbean.OpenType<?>,javax.management.Descriptor) in javax.management.openmbean.OpenMBeanParameterInfoSupport and method <T>OpenMBeanParameterInfoSupport(java.lang.String,java.lang.String,javax.management.openmbean.OpenType<T>,T) in javax.management.openmbean.OpenMBeanParameterInfoSupport match
                new OpenMBeanParameterInfoSupport("...", "...", openType, parameter.getDescriptor());
                ^

2 questions:

  1. I understand using raw types is a malpractice (openType should be declared as OpenType<?>, not OpenType), but how comes the ctor signatures are ambiguous? In the first case, the signature erasure is OpenMBeanParameterInfoSupport(String, String, OpenType, Descriptor), and in the second one OpenMBeanParameterInfoSupport(String, String, OpenType, Object), so javac should just pick the signature with the most specific type (i. e. Descriptor), shouldn't it?
  2. My colleagues claim they can successfully build the project with any 1.7 JDK, specifying -source 1.6 -target 1.6, while I'm the only one facing the compiler error. Is there any way to compile the code w/o changing it? The only workaround I sound is setting source level to 1.4, which is definitely not what our build server uses.
1

There are 1 best solutions below

3
On
both method 
OpenMBeanParameterInfoSupport(
                      java.lang.String,
                      java.lang.String,
                      javax.management.openmbean.OpenType<?>,
                      javax.management.Descriptor) 
  in javax.management.openmbean.OpenMBeanParameterInfoSupport 
and method 
<T> OpenMBeanParameterInfoSupport(
                      java.lang.String,
                      java.lang.String,
                      javax.management.openmbean.OpenType<T>,
                      T) 
  in javax.management.openmbean.OpenMBeanParameterInfoSupport 
match.

Indeed they do, the second method can be auto-resolved as <javax.management.Descriptor> while the first also matches because <?> is basically ? extends Object which could be anything including javax.management.Descriptor.

You would need to somehow change the signature so that they can't match when you call them. Even just switching the order on one of the parameters (the String with the OpenType for example) would fix the error.