为什么一类有效而另一类无效?

发布于 2024-09-06 22:43:15 字数 471 浏览 2 评论 0原文

正如您所看到的,具有非 void 返回类型很重要。

class TestValid {

public String f(List<String> list) {
    return null;
}

public Integer f(List<Integer> list) {
    return null;
}

public void test() {
    f(Arrays.asList("asdf"));
    f(Arrays.asList(123));
}

}

class TestInvalid {

public void f(List<String> list) {
    System.out.println("strings");
}

public void f(List<Integer> list) {
    System.out.println("numbers");
}

}

As you can see, having a non void return type is important.

class TestValid {

public String f(List<String> list) {
    return null;
}

public Integer f(List<Integer> list) {
    return null;
}

public void test() {
    f(Arrays.asList("asdf"));
    f(Arrays.asList(123));
}

}

class TestInvalid {

public void f(List<String> list) {
    System.out.println("strings");
}

public void f(List<Integer> list) {
    System.out.println("numbers");
}

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

无人问我粥可暖 2024-09-13 22:43:15

TestValid 开头无效:

TestValid.java:9:名称冲突:f(List) 和 f(List)
具有相同的擦除
公共整数 f(List 列表) {
               ^

所以返回类型是转移注意力的。如果在确定重载签名时考虑返回类型,那么它有效,但目前它与以下内容一样无效:

// Equally invalid
public Integer f() {}
public String f() {}

如果您确实设法让TestValid进行编译,我很想知道您正在使用哪种编译器。

TestValid isn't valid to start with:

TestValid.java:9: name clash: f(List<Integer>) and f(List<String>)
have the same erasure
public Integer f(List<Integer> list) {
               ^

So the return type is a red herring. If return types were taken into account in determining signatures for overloading, then it would be valid, but currently it's as invalid as this:

// Equally invalid
public Integer f() {}
public String f() {}

If you genuinely managed to get TestValid to compile, I'd be interested to know which compiler you're using.

心碎无痕… 2024-09-13 22:43:15

在第二种情况下,由于类型擦除,方法 f 在运行时无法区分。

http://java.sun.com/docs/books/ tutorial/java/generics/erasure.html

因此它们都具有完全相同的签名。

In the second case, the methods f cannot be distinguished at runtime due to type-erasure.

http://java.sun.com/docs/books/tutorial/java/generics/erasure.html

Thus they both have precisely the same signature.

放手` 2024-09-13 22:43:15

在编译的类型擦除部分之后,ListList 都是真正的 List 类型;在 TestInvalid 中,您正在使用相同的运行时签名创建两个方法。

After the type erasure part of compilation, List<String> and List<Integer> are both really type List; in TestInvalid you are making two methods with the same runtime signature.

又爬满兰若 2024-09-13 22:43:15

JDK1.5之前不支持协变返回类型;想想 Object.clone() 方法。以下内容可能会引起您的兴趣:

public class Base {
    public String f_array(List<String> strings) {
        StackTraceElement current = Thread.currentThread().getStackTrace()[1];
        System.out.println(String.format("%s#%s(strings)", current.getClassName(), current.getMethodName()));
        return null;
    }

    public Integer f_array(List<Integer> ints) {
        StackTraceElement current = Thread.currentThread().getStackTrace()[1]; 
        System.out.println(String.format("%s#%s(ints)", current.getClassName(), current.getMethodName()));
        return null;
    }

    public Number f() {
        StackTraceElement current = Thread.currentThread().getStackTrace()[1]; 
        System.out.println(String.format("%s#%s()", current.getClassName(), current.getMethodName()));
        return null;
    };

    public static class Child extends Base {
        @Override
        public Integer f() { //note Integer is_a Number
            StackTraceElement current = Thread.currentThread().getStackTrace()[1]; 
            System.out.println(String.format("%s#%s()", current.getClassName(), current.getMethodName()));
            return null;
        }
    }

    public static void main(String... args) {
        Base c = new Base();
        c.f_array(Arrays.asList(1));
        c.f_array(Arrays.asList("1"));
        c.f();
        c = new Child();
        c.f_array(Arrays.asList(1));
        c.f_array(Arrays.asList("1"));
        c.f();
    }
}

Covariant return type prior to JDK1.5 was not supported; think of Object.clone() method. The following might be of interest:

public class Base {
    public String f_array(List<String> strings) {
        StackTraceElement current = Thread.currentThread().getStackTrace()[1];
        System.out.println(String.format("%s#%s(strings)", current.getClassName(), current.getMethodName()));
        return null;
    }

    public Integer f_array(List<Integer> ints) {
        StackTraceElement current = Thread.currentThread().getStackTrace()[1]; 
        System.out.println(String.format("%s#%s(ints)", current.getClassName(), current.getMethodName()));
        return null;
    }

    public Number f() {
        StackTraceElement current = Thread.currentThread().getStackTrace()[1]; 
        System.out.println(String.format("%s#%s()", current.getClassName(), current.getMethodName()));
        return null;
    };

    public static class Child extends Base {
        @Override
        public Integer f() { //note Integer is_a Number
            StackTraceElement current = Thread.currentThread().getStackTrace()[1]; 
            System.out.println(String.format("%s#%s()", current.getClassName(), current.getMethodName()));
            return null;
        }
    }

    public static void main(String... args) {
        Base c = new Base();
        c.f_array(Arrays.asList(1));
        c.f_array(Arrays.asList("1"));
        c.f();
        c = new Child();
        c.f_array(Arrays.asList(1));
        c.f_array(Arrays.asList("1"));
        c.f();
    }
}
笑,眼淚并存 2024-09-13 22:43:15

对于 TestValid 类:
这些功能似乎超载。如果调用者传递类型已定义的参数 List 对象,则不会出现编译时错误。例如:new ArrayList()new ArrayList()
因为类型擦除后的签名(返回类型和输入参数)不一样。
但是,如果您传入 new ArrayList(),您将收到编译时错误。

第二个定义违反了重载函数的基本原则,其中两个函数在类型擦除后具有相同的签名(返回类型和输入参数)。

For TestValid class:
the functions appear to be overloaded. You wont get a compile time error if the caller passes a parameter List object which is type defined.eg: new ArrayList<Integer>() or new ArrayList<String>().
as the signature (return type and input parameters) after type erasure is not same.
However you will get compile time error if the you pass in new ArrayList().

The second definition violates the basic principle of overloading a function where two functions with same signature (return type and input parameters) after type erasure.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文