我有以下工厂类。它有两个采用Class实例并返回相应对象的方法。它们具有相同的方法名称,并且这两种方法都以Class作为参数,但具有不同的泛型类,也返回不同的类型。编译器是否认为这两种方法是重复的?当我打开Eclipse的Java文件,它像报告错误:具有不同泛型的方法参数是否使方法具有不同的签名?
描述资源路径位置类型 方法lookupHome(类)具有相同的擦除lookupHome(类),如类型的另一种方法EJBHomeFactory EJBHomeFactory.java
但是,它似乎不会报告任何错误。
import javax.ejb.EJBHome;
import javax.ejb.EJBLocalHome;
public class EJBHomeFactory {
public <T extends EJBHome> T lookupHome(Class<T> homeClass) throws PayrollException {
return lookupRemoteHome(homeClass);
}
public <T extends EJBLocalHome> T lookupHome(Class<T> homeClass) throws PayrollException {
return lookupLocalHome(homeClass);
}
/* ... define other methods ... */
}
更新1:这是使代码通过的蚂蚁脚本,我不知道它是如何工作的,但它不会引发任何错误。看起来编译器是Eclipse JDT编译器,我用常规的javac尝试过,并且它不能编译。
<target name="compile" depends="init" description="Compile Java classes">
<property name="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter"/>
<mkdir dir="${build.classes.dir}"/>
<javac destdir="${build.classes.dir}"
srcdir="${build.src.dir};${devsrc.dir}"
deprecation="${build.deprecation}"
debug="${build.debug}"
source="${build.source}"
target="${build.target}"
nowarn="${suppress.warning}"
bootclasspath="${bootclasspath}" >
<classpath>
<path refid="build.class.path.id"/>
</classpath>
</javac>
</target>
更新2:我刚刚创建另一个例子,有两个基类,并有两个子类,工厂类需要类和基于参数的类型实例。代码不能由javac编译,而在Eclipse中,IDE抱怨同样的擦除问题。下面是代码: 两个空基类:
public class BaseClassFirst {
}
public class BaseClassSecond {
}
两个子类:
public class SubClassFirst extends BaseClassFirst {
private int someValue = 0;
public SubClassFirst() {
System.out.println(getClass().getName());
}
public SubClassFirst(int someValue) {
this.someValue = someValue;
System.out.println(getClass().getName() + ": " + this.someValue);
}
}
public class SubClassSecond extends BaseClassSecond {
private int someValue = 0;
public SubClassSecond() {
System.out.println(getClass().getName());
}
public SubClassSecond(int someValue) {
this.someValue = someValue;
System.out.println(getClass().getName() + ": " + this.someValue);
}
}
因子类: 进口java.lang.reflect.Method中;
public class ClassFactory {
private static ClassFactory instance = null;
private ClassFactory() {
System.out.println("Welcome to ClassFactory!");
}
public static synchronized ClassFactory getInstance() {
if (instance == null) {
instance = new ClassFactory();
}
return instance;
}
public <T extends BaseClassFirst> T createClass(Class<T> firstClazz) {
if (firstClazz.equals(SubClassFirst.class)) {
try {
return firstClazz.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
return null;
}
public <T extends BaseClassSecond> T createClass(Class<T> secondClazz) {
if (secondClazz.equals(SubClassSecond.class)) {
try {
return secondClazz.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
return null;
}
public static void main(String[] args) {
ClassFactory factory = ClassFactory.getInstance();
SubClassFirst first = factory.createClass(SubClassFirst.class);
SubClassSecond second = factory.createClass(SubClassSecond.class);
for (Method method : ClassFactory.class.getDeclaredMethods()) {
System.out.println(method);
}
}
}
彼得,谢谢你的回答。这是否意味着编译器是否引发错误取决于这两种方法的调用方式?或者在极端的情况下,如果这两种方法从未被调用过,编译器会在这两种方法上抛出错误? – Sapience 2011-02-24 19:22:03
返回类型不是签名的一部分。 – jprete 2011-02-25 06:53:42
@jprete,返回类型是字节码级别签名的一部分,正如我已经演示的那样。你如何支持你的陈述? – 2011-02-25 09:09:01