我很困惑,为什么第一个代码段无法编译,而第二个代码段却没有编译?
我假设在两种情况下,通用参数T描述了相同的可能类型集,因此它们是等效的。
第一个示例
public class Main {
static Function<B, Integer> f = (b) -> 1;
Main() {
this(f);
}
<T extends A> Main(Function<T, Integer> f) {
}
}
class A { }
class B extends A { }
第二个示例:
public class Main<T extends A> {
static Function<B, Integer> f = (b) -> 1;
Main() {
this(f);
}
Main(Function<T, Integer> f) {
}
}
class A { }
class B extends A { }
产生错误:
The constructor Main <T>(Function<B,Integer>) is undefined
答案 0 :(得分:3)
在第二个示例中,在类级别引入类型参数T,但是始终将使用类B传递固定函数。如果用Main«A»实例化Main怎么办?您的代码类型不安全。
在您的第一个示例中,这不是问题,因为函数的type参数仅在每次调用时确定。
答案 1 :(得分:3)
在第一个代码中,{
"name": "my-testapp",
"version": "0.0.0",
"license": "MIT",
"scripts": {
"ng": "ng",
"start": "ng serve --base-href /mytestapp/",
"build": "ng build",
"build-stage": "ng build --environment=stage --aot --prod --vendor-chunk=false --common-chunk=false",
"build-prod": "ng build --environment=prod --aot --prod --vendor-chunk=false --common-chunk=false",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
},
"private": true,
"dependencies": {
"@angular/animations": "^4.2.4",
"@angular/common": "^4.2.4",
"@angular/compiler": "^4.2.4",
"@angular/core": "^4.2.4",
"@angular/forms": "^4.2.4",
"@angular/http": "^4.2.4",
"@angular/platform-browser": "^4.2.4",
"@angular/platform-browser-dynamic": "^4.2.4",
"@angular/router": "^4.2.4",
"@ngx-translate/core": "^7.2.2",
"@ngx-translate/http-loader": "^1.1.0",
"bootstrap": "^3.3.7",
"core-js": "^2.4.1",
"jquery": "^3.2.1",
"qrcode": "^1.0.0",
"rxjs": "^5.4.2",
"zone.js": "^0.8.14"
},
"devDependencies": {
"@angular/cli": "1.4.2",
"@angular/compiler-cli": "^4.2.4",
"@angular/language-service": "^4.2.4",
"@types/jasmine": "~2.5.53",
"@types/jasminewd2": "~2.0.2",
"@types/node": "~6.0.60",
"codelyzer": "~3.1.1",
"jasmine-core": "~2.6.2",
"jasmine-spec-reporter": "~4.1.0",
"karma": "~1.7.0",
"karma-chrome-launcher": "~2.1.1",
"karma-cli": "~1.0.1",
"karma-coverage-istanbul-reporter": "^1.2.1",
"karma-jasmine": "~1.1.0",
"karma-jasmine-html-reporter": "^0.2.2",
"protractor": "~5.1.2",
"ts-node": "~3.2.0",
"tslint": "~5.3.2",
"typescript": "~2.3.3"
}
}
参数的作用域为方法:
T
它使用目标的推断(客户端声明的类型返回)来确定<T extends A> Main(Function<T, Integer> f) {
}
的值。
因此,只有在T
的第一种类型是Function
或A
的子类时才可以编译,以遵守A
约束。
例如,声明其他这些类:
<T extends A>
这些也将起作用:
class B extends A { }
class C extends A { }
class D extends B { }
在第二个代码中,您要将一个static Function<B, Integer> fb = (b) -> 1;
static Function<C, Integer> fc = (b) -> 1;
static Function<D, Integer> fd = (b) -> 1;
声明的变量传递给依赖于该类的Function<B, Integer>
泛型类型的Main
构造函数:
T
问题在于,根据类的客户端使用的通用类型,此处的public class Main<T extends A> {
Main(Function<T, Integer> f) {
}
}
可能是T
,A
或B
的任何其他子类。 br />
因此A
无法分配给Function<B, Integer>
,并且编译失败。
答案 2 :(得分:0)
这些例子不一样。
示例1-只有构造函数#2是通用的,而构造函数#1和类不是通用的。
因此,编译器仅需在构造#1中推断构造2的参数类型。那很好并且可能。
示例2-整个类都是通用的。
因此,已经针对建筑#1的编译器使用类型.psqlrc
。现在,它检查对构造2的调用。结果表明T extends A
不等于T extends A
(B
可以是扩展T
的任何其他类)。
要澄清-对于泛型类,类型推断(泛型类型的解析)不能在构造函数中发生。它发生在从外部调用构造函数的地方。里面已经完全按照定义给出了。
与该示例相比,仅使用方法(构造函数)类型推断,这可以在构造#1中完美实现。