来自类别MyClass的getMethod()的类型为String,与描述符的返回类型U不兼容。

huangapple go评论116阅读模式
英文:

The type of getMethod() from the type MyClass is String, this is incompatible with the descriptor's return type: U

问题

public class MyClass {
    private String name;
    private String status;
    private Double risk;
    private Double health;
    // more variables with all getters and setters
}

private static <T extends MyClass, U extends Comparable<U>> Function<T, U> getSortFunction(final String fieldName) {
    Function<T, U> func = null;
    if ("name".equalsIgnoreCase(fieldName)) {
        func = MyClass::getName;
    } else if ("risk".equalsIgnoreCase(fieldName)) {
        func = MyClass::getRisk;
    }
    return func;
}

在上面的代码中,您有一个简单的Java类MyClass,其中包含一些变量(String,Double,Integer等)和相应的getter和setter方法。您尝试编写一个通用方法getSortFunction,该方法将返回Function<T, U>类型,以便进一步用于排序。但是在代码的两个地方出现了编译时错误:

  1. 第一个错误出现在func = MyClass::getName;这一行:

    MyClassgetName()方法返回的类型是String,与描述符的返回类型U不兼容。

  2. 第二个错误出现在func = MyClass::getRisk;这一行:

    MyClassgetRisk()方法返回的类型是Double,与描述符的返回类型U不兼容。

您的函数的返回类型是Comparable类型,但是出现了类型不兼容的问题。请问您是否需要进一步的指导?

英文:

I have a simple java class with some variables String, Double, Integer etc.

public class MyClass {
	private String name;
	private String status;
	private Double risk;
	private Double health;
	// more variables with all getters and setters
}

I am trying to write a generic method which will return the Function&lt;T, U&gt; type. I will further use this function for sorting. It is throwing compile time error
> The type of getName() from the type MyClass is String, this is incompatible with the descriptor's return type: U

at line func = MyClass::getName;

and error
> The type of getRisk() from the type MyClass is Double, this is incompatible with the descriptor's return type: U

at line func = MyClass::getRisk;

     private static &lt;T extends MyClass, U extends Comparable&lt;U&gt;&gt; Function&lt;T, U&gt; getSortFunction(final String fieldName) {
		Function&lt;T, U&gt; func = null;
		if (&quot;name&quot;.equalsIgnoreCase(fieldName)) {
			func = MyClass::getName;
		} else if (&quot;risk&quot;.equalsIgnoreCase(fieldName)) {
			func = MyClass::getRisk;
		}
		return func;
	}

The return type of my function is of Comparable type not sure what wrong I am doing here. Any pointers?

答案1

得分: 0

&lt;T extends MyClass, U extends Comparable&lt;U&gt;&gt; :这是类型推断问题。这个问题已经在一个问题中讨论过:https://stackoverflow.com/questions/24436871/very-confused-by-java-8-comparator-type-inference

要修复这个问题,你可以进行以下操作:

  • 改变返回类型:将private static &lt;T extends MyClass, U extends Comparable&lt;U&gt;&gt; Function&lt;T, U&gt; 改为private static Comparator&lt;MyClass&gt;

  • 基于字段名称返回Comparator.comparing:

if ("name".equalsIgnoreCase(fieldName)) {
    func = Comparator.comparing(MyClass::getName);

完整代码:

private static Comparator&lt;MyClass&gt; getSortFunction(final String fieldName) {
    Comparator&lt;MyClass&gt; func = null;
    if ("name".equalsIgnoreCase(fieldName)) {
        func = Comparator.comparing(MyClass::getName);
    } else if ("risk".equalsIgnoreCase(fieldName)) {
        func = Comparator.comparing(MyClass::getRisk);
    }
    return func;
}

public static void main(String[] args) {
    List&lt;MyClass&gt; myClassList = //init list;
    myClassList.sort(getSortFunction("name"));
}
英文:

&lt;T extends MyClass, U extends Comparable&lt;U&gt;&gt; : This is type inference problem. This has be discussed in a question: https://stackoverflow.com/questions/24436871/very-confused-by-java-8-comparator-type-inference

To fix the problem you can do the following:

  • Change the return type: private static &lt;T extends MyClass, U extends Comparable&lt;U&gt;&gt; Function&lt;T, U&gt; to private static Comparator&lt;MyClass&gt;?

  • Return Comparator.comparing based on the field name:

if (&quot;name&quot;.equalsIgnoreCase(fieldName)) {
            func = Comparator.comparing(MyClass::getName);

Complete code:

    private static Comparator&lt;MyClass&gt; getSortFunction(final String fieldName) {
        Comparator&lt;MyClass&gt; func = null;
        if (&quot;name&quot;.equalsIgnoreCase(fieldName)) {
            func = Comparator.comparing(MyClass::getName);
        } else if (&quot;risk&quot;.equalsIgnoreCase(fieldName)) {
            func = Comparator.comparing(MyClass::getRisk);
        }
        return func;
    }

    public static void main(String[] args) {
        List&lt;MyClass&gt; myClassList = //init list;
        myClassList.sort(getSortFunction(&quot;name&quot;));
    }


答案2

得分: 0

Java泛型主要是关于开发者承诺所使用/返回的实例将满足某些类型限制。

那么关于getSortFunction()的结果类型,您做出了什么承诺呢?您编写了:

private static <T extends MyClass, U extends Comparable<U>> Function<T, U> getSortFunction(final String fieldName)

表示:

  • 该方法将返回一个接受T并返回UFunction
  • 这个Function将接受某个未指定的MyClass子类T
  • 这个Function将返回一些Comparable类的实例U

当编译器看到例如getSortFunction("name")的调用时,他无法确定TU的具体类型,无法确定生成的FunctionFunction<MyClass, String>还是Function<MySubclass, Long>,因此您声明的泛型部分并没有提供帮助。编译器唯一的机会是查看方法调用的预期结果,例如:

Function<MyClass, String> fun = getSortFunction("hometown");

在这种情况下,TMyClassUString。当然,方法体必须以适用于所有可能的调用模式的方式编写,因此相同的方法体必须同时适用于一个期望Function<MyClass, String>的调用和一个期望Function<MySubclass, Long>的调用。返回MyClass::getName只与第一个调用模式匹配,而不与例如Function<MySubclass, Long>匹配。

这就是为什么您会得到编译错误。

英文:

Java Generics is all about you as developer promising that the instances used/returned will fulfill some type restrictions.

So, what is it that you promise about the result type of getSortFunction()? You write:

private static &lt;T extends MyClass, U extends Comparable&lt;U&gt;&gt; Function&lt;T, U&gt; getSortFunction(final String fieldName)

meaning:

  • The method will return a Function accepting T and returning U.
  • The Function will accept some unspecified subclass T of MyClass.
  • The Function will return instances of U, being some Comparable class.

When the compiler sees a call of e.g. getSortFunction(&quot;name&quot;), he has no hint what to conclude for T and U, whether the resulting Function will be a Function&lt;MyClass,String&gt; or a Function&lt;MySubclass,Long&gt;, so the generics part of your declaration isn't helpful. The compiler's only chance is to look at the expected result of the method call, e.g.

Function&lt;MyClass,String&gt; fun = getSortFunction(&quot;hometown&quot;);

In this case, T is MyClass, and U is String. Of course, the method body must be written in a way applicable to all possible call patterns, so the same method body must match both a call expecting a Function&lt;MyClass,String&gt; and one expecting a Function&lt;MySubclass,Long&gt;. Returning MyClass::getName only matches the first call pattern and not e.g. a Function&lt;MySubclass,Long&gt;.

That's why you get the compile error.

huangapple
  • 本文由 发表于 2020年9月20日 04:11:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/63973015.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定