有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java泛型函数返回声明

我是Java泛型新手,并且已经成功地获得了一个getKeyByValue函数与HashMap<String, String>一起工作,但是我不理解函数声明是如何不明确/冗余并且仍然工作的。例如,这两个声明都有效,但第一个声明对我来说意义不大:

    private <T, E> String getKeyByValue(Map<String, E> map, String value) {
        for (Entry<String, E> entry : map.entrySet()) {
            if (value.equals(entry.getValue())) {
                return entry.getKey();
            }
        }
        return null;
    }

仅使用<E>的示例:

    private <E> String getKeyByValue(Map<String, E> map, String value) {
        for (Entry<String, E> entry : map.entrySet()) {
            if (value.equals(entry.getValue())) {
                return entry.getKey();
            }
        }
        return null;
    }

共 (3) 个答案

  1. # 1 楼答案

    对于第一个示例,没有使用泛型格式类型T,因此可以将其删除,从而使实现成为第二个方法实现

    在第二个实现中,Java泛型的用法没有任何实用程序,因为equals方法(您使用类型化参数E调用,java.lang.String类接受一个Object参数,因此任何对象都可以放入其中

    private <E> String getKeyByValue(Map<String, E> map, String value) {
        for (Map.Entry<String, E> entry : map.entrySet()) {
            if (value.equals(entry.getValue())) { // there is no type checking needed over the value as it can be any acceptable object
                return entry.getKey();
            }
        }
        return null;
    }
    

    可以使用?通配符作为形式类型重写相同的方法,因为在Map值上不需要类型有界的操作:

    private String getKeyByValue(Map<String, ?> map, String value) {
        for (Map.Entry<String, ?> entry : map.entrySet()) {
            if (value.equals(entry.getValue())) {
                return entry.getKey();
            }
        }
        return null;
    }
    
  2. # 2 楼答案

    对于第一种情况,类型参数T显然是冗余的

    从另一个角度来看,类似的情况是在不使用方法输入参数的情况下声明方法输入参数。你可能认为编译器不应该允许我们这么做。但是,有时候这种“灵活性”是有用的。例如,我们可能有一个父类,它有一个只在子类中使用的带有输入参数的方法。虽然我想不出冗余类型参数有用的场景,但有人可能会利用这种语言灵活性来解决他们的问题

    我想说,第一种情况应该被视为代码气味,就像空if语句,或者声明未使用的变量一样。IDE和linter是解决这些问题的正确工具,而不是编译器

  3. # 3 楼答案

    您的第一个示例只是声明从未使用过的类型参数——您可以声明任意多的类型参数

    private <T, E, F, G> String getKeyByValue(Map<String, E> map, String value) {
        for (Entry<String, E> entry : map.entrySet()) {
            if (value.equals(entry.getValue())) {
                return entry.getKey();
            }
        }
        return null;
    }