对Java通配符感到困惑

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

Confused with Java wildcards

问题

我对Java泛型很陌生感到非常困惑

我编写了这些代码但是遇到了错误"所需类型:? extends Number 的捕获,实际提供:Integer"

出了什么问题

import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;

public class TestGeneric {

  // 我想创建一个Function列表,这些Function的输入/输出类型可以彼此不同。
  private List<Function<? extends Number, ? extends Number>> functions;

  public TestGeneric() {
    functions = new ArrayList<>();
  }

  public void addFunction(Function<? extends Number, ? extends Number> function) {
    functions.add(function);
  }

  public static void main(String[] args) {

    TestGeneric testGeneric = new TestGeneric();

    Function<Integer, Integer> hundredTimes = new Function<Integer, Integer>() {
      @Override
      public Integer apply(Integer integer) {
        return integer * 100;
      }
    };

    testGeneric.addFunction(hundredTimes);

    Function<Double, Double> tenTimes = new Function<Double, Double>() {
      @Override
      public Double apply(Double o) {
        return 10.0 * o;
      }
    };

    testGeneric.addFunction(tenTimes);

    System.out.println(testGeneric.functions.get(0).apply(Integer.valueOf(10)));
  }
}
英文:

I am new to Java generics and I am so confused.

I wrote this piece of codes, but I got error "Required type:
capture of ? extends Number, Provided: Integer".

What went wrong?

import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
public class TestGeneric {
// I want to create a list of Functions, and these Functions can have different input/output types than one another.
private List&lt;Function&lt;? extends Number, ? extends Number&gt;&gt; functions;
public TestGeneric() {
functions = new ArrayList&lt;&gt;();
}
public void addFunction(Function&lt;? extends Number, ? extends Number&gt; function) {
functions.add(function);
}
public void main(String[] args) {
TestGeneric testGeneric = new TestGeneric();
Function&lt;Integer, Integer&gt; hundredTimes = new Function&lt;Integer, Integer&gt;() {
@Override
public Integer apply(Integer integer) {
return integer * 100;
}
};
functions.add(hundredTimes);
Function&lt;Double, Double&gt; tenTimes = new Function&lt;Double, Double&gt;() {
@Override
public Double apply(Double o) {
return 10.0 * o;
}
};
functions.add(tenTimes);
System.out.println(functions.get(0).apply(Integer.valueOf(10)));
}
}

答案1

得分: 1

主要问题是您的函数列表的定义:

private List<Function<? extends Number, ? extends Number>> functions;

我建议您尝试针对您的情况使用:

private List<Function<Number, ? extends Number>> functions;

然后稍微修改其他函数...

Function<Number, Integer> hundredTimes = integer -> integer.intValue() * 100;
functions.add(hundredTimes);

Function<Number, Double> tenTimes = o -> 10.0 * o.doubleValue();
functions.add(tenTimes);

System.out.println(functions.get(0).apply(Integer.valueOf(10)));

使用Lambda表达式,您最终可以编写:

functions.add(n -> n.intValue() * 100);
functions.add(n -> 10.0 * n.doubleValue());
System.out.println(functions.get(0).apply(10));

问题在于通配符的含义与您最初的想法不同。使用通配符意味着您使用了特定的类型,但您不知道它是什么。在您要将10添加为整数时,函数要求特定的类型,而这个类型是?。因此,这样是行不通的。也许在方法或类上使用泛型,根据用例,也可以解决您的问题。但是更改为Number应该能解决问题。

英文:

The main problem is the definition of your functions list

private List&lt;Function&lt;? extends Number, ? extends Number&gt;&gt; functions;

I would try to use for your case:

private List&lt;Function&lt;Number, ? extends Number&gt;&gt; functions;

Then modify the other functions a little bit...

Function&lt;Number, Integer&gt; hundredTimes = new Function&lt;Number, Integer&gt;() {
@Override
public Integer apply(Number integer) {
return integer.intValue() * 100;
}
};
functions.add(hundredTimes);
Function&lt;Number, Double&gt; tenTimes = new Function&lt;Number, Double&gt;() {
@Override
public Double apply(Number o) {
return 10.0 * o.doubleValue();
}
};
functions.add(tenTimes);
System.out.println(functions.get(0).apply(Integer.valueOf(10)));

Using lambdas you could finally write:

functions.add( n -&gt; n.intValue() * 100);
functions.add(n -&gt; 10.0 * n.doubleValue());
System.out.println(functions.get(0).apply(10));

The problem is that the wildcard has an other meaning than you think by first thoughts. Using a wildcard means you use a specific type but you dont know it. At the time you want to add 10 as an int, the function asks for the specific type which is ?. So this will not work. Perhaps using generics on methods or on the class could solve your problem also depending on the use case. But change to Number should solve the problem.

huangapple
  • 本文由 发表于 2020年10月21日 01:10:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/64450121.html
匿名

发表评论

匿名网友

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

确定