ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Java 8通用java.util.Function

2019-11-18 10:11:01  阅读:322  来源: 互联网

标签:functional-interface java-8 generics java


我正在学习Java 8中提供的FunctionalInterface.在完成一些基本的Functional示例之后,我尝试对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编译器抛出错误为

AreaService类型未定义适用于此处的createArea(T)

在FunctionalInterface ..中不能定义泛型类型参数吗?

解决方法:

您可以在此处将Class类用作类型标记. (我将忽略您发布的代码中的一些明显问题,例如无法调用新的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的类文字T.class的类型为Class< T>.因此Area.class的类型为Class< Area>,Country.class的类型为Class< Country>.

因此,如果调用getCreateFunction(Area.class),则编译器可以推断该调用中T为Area,然后返回类型为Function< Area,Area>.另一方面,在getCreateFunction的实现中,尽管编译器只能推断出lambda的参数是未知类型T,但我们知道它T必须是由参数类型表示的类型;即,如果type == Area.class,我们可以安全地将t强制转换为Area,并将(areaService.createArea返回的值)强制转换为T.因此强制转换是安全的(甚至强制转换为未知类型T).

如果您想进一步限制可以传递给getCreateFunction(…)的值,则可以定义一个标记接口:公共接口Region {},并让Area和Country实施该接口.然后定义

public <T extends Region> Function<T,T> getCreateFunction(Class<T> type) {...}

并且仅对实现(或扩展了接口)Region的类传递类令牌是有效的.

标签:functional-interface,java-8,generics,java
来源: https://codeday.me/bug/20191118/2027612.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有