Java Generic:特定参数类型的静态方法不匹配功能接口

发布于 2025-01-30 08:21:15 字数 544 浏览 6 评论 0原文

下面的第一个分配未编译,但我不确定为什么,静态方法的方法签名与功能方法签名匹配,尽管它不使用类型参数。第二行填充了罚款,即使它是相同的签名,除了类型的参数化。

这背后的原因是什么?

public class GenericSample<T> {
    public static void staticLambdaMtd(Integer a) {
            
    }   

    public static<X> void staticLambdaMtd2(X a) {
            
    }  

    // Funca<T> fa1 = GenericSample::staticLambdaMtd;//does not compile !

    Funca<T> fa = GenericSample::staticLambdaMtd2;//does compile !      
}
    
interface Funca<A> {
    public void funct(A a);
}

The first assignment below doesn't compile, but I am not sure why, the method signature of the static method matches the functional method signature albeit it is not using type arguments. The second line compiles fine even though it is the same signature except for the type parameterization.

What is the reasoning behind this?

public class GenericSample<T> {
    public static void staticLambdaMtd(Integer a) {
            
    }   

    public static<X> void staticLambdaMtd2(X a) {
            
    }  

    // Funca<T> fa1 = GenericSample::staticLambdaMtd;//does not compile !

    Funca<T> fa = GenericSample::staticLambdaMtd2;//does compile !      
}
    
interface Funca<A> {
    public void funct(A a);
}

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

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

发布评论

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

评论(1

×眷恋的温暖 2025-02-06 08:21:15

您正在混合通用参数t和类型整数。这是行不通的,因为t整数是不同的类型。

仿制药是不变的。这意味着您可以分配给list&lt; person&gt;仅具有相同通用参数的另一个列表,即person(不是integer> CATt)。同样,我们也无法将funca&lt; gt;分配给类型funca&lt; t&gt;的变量。

有关更多信息,请看一下 tutorial

>由Oracle提供的 funca&lt; t&gt; - IE某种任意类型的函数,因为只有整数类型类型与方法签名匹配,但不符合任何类型(例如String) ,catbigDecimal)将在类genericsample将得到实例化时定义。

第二个语句编编译,因为它不会期望任何特定类型。 X只是占位符,t。 Expression genericsample :: staticlambdamtd2应分类为SO-CALLED poly表达式 ,即,因为您不提供类型的编译器需要从分配上下文中推断出来。

因此,将推断出Expression genericsample :: staticlambdamtd2是类型为funca&lt; t&gt;,第二个语句将符合正常。

下面显示的所有作业都是有效的:

// expression on the right could represent only `Funca<Integer>`

Funca<Integer> fa1 = GenericSample::staticLambdaMtd;


// expression on the right can be succefully inferred to 
// a function of any type based on the assingment context on the left

Funca<T> fa = GenericSample::staticLambdaMtd2;      
Funca<String> fa = GenericSample::staticLambdaMtd2;
Funca<BigDecimal> fa = GenericSample::staticLambdaMtd2;

注释 表达式genericsample :: staticlambdamtd2可以从 poly expression 转动到a “独立形式” 通过提供一个通用参数(实际上,按规范中提供的定义方法参考始终是poly expressions ,因此我使用了“我使用过”独立的“引号”标记仅表示分配上下文将被忽略)。

而且我们如何打破它:

// that will not compile for the same reason as the the firt statement doesn't compile

Funca<T> fa3 = GenericSample::<Integer>staticLambdaMtd2;

You are mixing a generic parameter T and a type Integer. That wouldn't work because T and Integer are different types.

Generics are invariant. That means you can assign to a List<Person> only another list having the same generic parameter, i.e. Person (not Integer, Cat or T). Similarly, we can't assign Funca<Integer> to a variable of type Funca<T>.

For more information, have a look at this tutorial provided by Oracle.

A function created using a static method staticLambdaMtd(Integer a) is assignable only to a variable of type Funca<Integer>, but not Funca<T> - i.e. function of some arbitrary type, because only Integer type would match the method signature, but not any type (like String, Cat, BigDecimal) that would be defined while class GenericSample will get instantiated.

The second statement compiles fine, because it doesn't expect any specific type. X is only a placeholder, as well as T. And expression GenericSample::staticLambdaMtd2 should be classified as a so-called poly expression, i.e. because you're not providing a type compiler needs to infer it from the assignment context.

Therefore, the expression GenericSample::staticLambdaMtd2 would be inferred as being of type Funca<T> and the second statement will compile fine.

All assignments shown below are valid:

// expression on the right could represent only `Funca<Integer>`

Funca<Integer> fa1 = GenericSample::staticLambdaMtd;


// expression on the right can be succefully inferred to 
// a function of any type based on the assingment context on the left

Funca<T> fa = GenericSample::staticLambdaMtd2;      
Funca<String> fa = GenericSample::staticLambdaMtd2;
Funca<BigDecimal> fa = GenericSample::staticLambdaMtd2;

Note that expression GenericSample::staticLambdaMtd2 can be turned from a poly expression into a "standalone form" by providing a generic parameter (in fact, method references by definition provided in the specification are always poly expressions, therefore I've used "standalone" in quotation marks meaning only that assignment context will be ignored).

And that we how can break it:

// that will not compile for the same reason as the the firt statement doesn't compile

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