我有以下工厂类。它有两个方法,它们接受 Class 实例并返回相应的对象。它们具有相同的方法名称,并且两个方法都以 Class 作为参数但具有不同的泛型类,也返回不同的类型。编译器是否认为这两个方法是重复的?当我在 Eclipse 中打开 java 文件时,它报告如下错误:
描述资源路径位置类型 方法 lookupHome(Class) 与类型 EJBHomeFactory EJBHomeFactory.java 中的另一个方法具有相同的删除 lookupHome(Class)
但是,javac 似乎不会报告任何错误。
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:这是使代码通过的 ant 脚本,我不确定它是如何工作的,但它不会抛出任何错误。编译器似乎是 Eclipse JDT Compiler,我尝试使用常规 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:我只是创建了另一个示例,有两个基类和两个子类,一个工厂类采用 Class 并根据参数的类型生成实例。代码无法通过 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);
}
}
}
最佳答案
当方法可以在编译时解析时,这是可行的,因为返回类型是签名的一部分。删除后你有两种方法
public EJBHome lookupHome(Class homeClass) throws PayrollException;
public EJBLocalHome lookupHome(Class homeClass) throws PayrollException;
您不能在没有泛型的情况下定义它们,但由于返回类型是签名的一部分,因此这些是不同的方法。
你可以调用
lookupHome(EJBHome.class);
lookupHome(EJBLocalHome.class);
但不是
Class c= EJBHome.class;
lookupHome(c); // Ambiguous method call.
编辑:尝试以下操作。
for (Method method : EJBHomeFactory.class.getDeclaredMethods()) {
System.out.println(method);
}
你应该会看到类似的东西
public javax.ejb.EJBHome EJBHomeFactory.lookupHome(java.lang.Class)
public javax.ejb.EJBLocalHome EJBHomeFactorylookupHome(java.lang.Class)
同样,如果您使用 javap -c。
调用虚拟#8;//方法lookupHome:(Ljava/lang/Class;)Ljavax/ejb/EJBHome;
调用虚拟#10;//方法lookupHome:(Ljava/lang/Class;)Ljavax/ejb/EJBLocalHome;
编辑如果你想要一个返回类型是签名一部分的例子..
class A {
public static Byte getNum() { return 0; }
}
class B {
public static void main(String ... args) {
int i = A.getNum();
System.out.println(i);
}
}
编译运行,没有报错,现在把A中getNum的签名改成
class A {
public static Integer getNum() { return 0; }
}
并且只编译类 A。如果返回类型不是签名的一部分,这对 B 没有影响,但是如果你运行 B 而不重新编译它,你会得到
Exception in thread "main" java.lang.NoSuchMethodError: A.getNum()Ljava/lang/Byte;
at B.main(B.java:10)
如您所见,返回类型Ljava/lang/Byte;
是返回类型的内部名称和签名的一部分。
关于java - 具有不同泛型的方法参数是否使方法具有不同的签名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5109146/