我正在学习Java 8中存在的FunctionalInterface
。在做了一些基本的功能示例之后,我尝试对GenericType参数做同样的事情。
public class Main {
public enum LocType {
Area, Country
}
public <T> Function<T, T> getCreateFunction(LocType type) {
AreaService areaService = new AreaService();
CountryService countryService = new CountryService();
switch(type) {
case Area : return areaService::createArea;
case Country : return countryService::createCountry;
default : return null;
}
}
}
public class AreaService {
public Area createArea(Area area) {
// some logic
return area;
}
}
public class CountryService {
public Country createCountry(Country country) {
// some logic
return country;
}
}
// Area & Country are Model Classes
但是eclipse编译器会抛出错误
The type AreaService does not define createArea(T) that is applicable here
是不是可以在FunctionalInterface中定义通用类型参数..?
答案 0 :(得分:3)
您可以在此处使用Class
类作为类型标记。 (我将忽略您发布的代码的一些明显问题,例如无法调用new AreaService()
等)。您可以使用Class
作为参数,而不是为您希望函数创建(操作?)的事物类型定义枚举,而是使用@SuppressWarnings("unchecked")
public <T> Function<T, T> getCreateFunction(Class<T> type) {
AreaService areaService = new AreaService();
CountryService countryService = new CountryService();
if (type == Area.class) {
return t -> (T) areaService.createArea((Area)t);
} else if (type == Country.class) {
return t -> (T) countryService.createCountry((Country)t);
}
return null ; // may be better to throw an IllegalArgumentException("Unsupported type")
}
作为参数:
Main main = new Main();
Function<Area, Area> areaChanger = main.getCreateFunction(Area.class);
Function<Country, Country> countryChanger = main.getCreateFunction(Country.class);
现在你可以做一些事情,比如
T.class
这样做的方式是任何类T
的类文字Class<T>
都是Area.class
类型。因此Class<Area>
的类型为Country.class
,而Class<Country>
的类型为getCreateFunction(Area.class)
。
因此,如果您调用T
,编译器可以在该调用中推断出Area
为Function<Area, Area>
,然后返回类型为getCreateFunction
。另一方面,在T
的实现中,虽然编译器只能推断lambda的参数是未知类型T
,但我们知道它type
必须属于由参数type==Area.class
表示的类型;即如果t
,我们可以安全地将Area
投放到areaService.createArea
和(Area
)T
返回的值T
。因此,演员阵容是安全的(甚至是演员到未知类型getCreateFunction(...)
)。
如果您想进一步限制可传递给public interface Region { }
的值,您可以定义标记界面:例如Area
并使Country
和public <T extends Region> Function<T,T> getCreateFunction(Class<T> type) {...}
实现该接口。然后定义
Region
只有为实现的类(或扩展的接口)app.controller('MainController', ['$scope',function(a){
传递类令牌才有效。
答案 1 :(得分:0)
可以定义泛型类型参数。你可以在jdk中找到像
这样的例子default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
static <T> Function<T, T> identity() {
return t -> t;
}
在您的示例中不起作用的是areaService::createArea
和countryService::createCountry
对于具体类型是Functions
。
编译器无法将Area
分配给泛型类型T
。因为T
可以是Integer
或Stream