当前位置: 首页 > wzjs >正文

住房和城乡建设部网站预售证全国知名网站排名

住房和城乡建设部网站预售证,全国知名网站排名,开发一个app最少需要多少钱,触动网站建设在日常开发中我们经常会遇到泛型和通配符类型&#xff08;WildcardType&#xff09;&#xff0c;比如当我们需要处理List<? extends Number>这样的类型时&#xff0c;如何优雅地创建这样的类型表示&#xff1f;本文将重点介绍如何通过Guava的TypeToken来实现通配符类型的…

在日常开发中我们经常会遇到泛型和通配符类型(WildcardType),比如当我们需要处理List<? extends Number>这样的类型时,如何优雅地创建这样的类型表示?本文将重点介绍如何通过Guava的TypeToken来实现通配符类型的构造,并结合开源项目中的实践进行深入解读。


一、通配符类型的痛点

在Java的泛型系统中,通配符类型(如<? extends T><? super T>)能提供更灵活的类型约束。但在反射场景中,我们无法直接通过new操作符或Class对象创建这种类型,这在需要动态生成类型的场合非常棘手。

考虑如下场景:

// 如何用代码表示List<? extends Number>类型?
Type listType = new ParameterizedType() {public Type[] getActualTypeArguments() {return new Type[] { /* 如何表示? extends Number */ };}// ...
}

我们希望能有一个工具来优雅地构造这样的通配符类型。


二、WildcardTyper工具类解析

以下是一个专为通配符类型设计的工具类,来自真实项目代码:

public abstract class WildcardTyper<T> {public final WildcardType wildcardType;protected WildcardTyper(boolean subType) {TypeToken<?> token = subType ? new TypeToken<Class<? extends T>>() {} : new TypeToken<Class<? super T>>() {};this.wildcardType = (WildcardType) ((ParameterizedType) token.getType()).getActualTypeArguments()[0];}// 子类型快捷方式public abstract static class SubOf<T> extends WildcardTyper<T> {public SubOf() { super(true); }}// 超类型快捷方式public abstract static class SuperOf<T> extends WildcardTyper<T> {public SuperOf() { super(false); }}
}

核心原理:

  1. TypeToken魔法:利用Guava的TypeToken捕获泛型参数类型信息
  2. 参数类型提取:构造如Class<? extends T>的参数化类型,从中提取通配符类型
  3. 子类化技巧:通过继承时的具体类型声明保留泛型参数信息

三、实战使用示例

示例1:创建基础通配符类型
// ? extends Number
WildcardType extendsNumber = new WildcardTyper.SubOf<Number>() {}.wildcardType;// ? super Integer
WildcardType superInteger = new WildcardTyper.SuperOf<Integer>() {}.wildcardType;
示例2:复杂容器类型构建
// List<? extends Number>
Type listOfNumbers = new ParameterizedTypeImpl(List.class, new Type[] { new WildcardTyper.SubOf<Number>() {}.wildcardType }
);// Map<String, ? super Date>
Type mapWithSuper = new ParameterizedTypeImpl(Map.class,new Type[] { String.class, new WildcardTyper.SuperOf<Date>() {}.wildcardType }
);
示例3:类型系统验证
@Test
public void testTypeCompatibility() {// 验证Float可以赋值给? extends NumberWildcardType numType = new WildcardTyper.SubOf<Number>() {}.wildcardType;assertTrue(TypeToken.of(numType).isSupertypeOf(Float.class));// 验证List<? extends Number>能接受ArrayList<Double>ParameterizedType listType = new ParameterizedTypeImpl(List.class, new Type[] { numType });assertTrue(TypeToken.of(listType).isSupertypeOf(ArrayList.class));
}

四、高级技巧:类型转换中的通配符处理

在BaseTypeTransformer的代码中,我们看到了这样的高级应用:

// 定义从Date到子类型的转换器
transTable.put(Date.class, new WildcardTyper.SubOf<Date>() {}.wildcardType, new Date2SubTransformer()
);// 转换器实现
class Date2SubTransformer extends BaseFunction<Date, Date> {public Date doApply(Date input) {return (Date) outputType.getRawType().getConstructor(long.class).newInstance(input.getTime());}
}

工作原理:

  1. 通过SubOf<Date>声明目标类型为? extends Date
  2. 运行时动态确定实际类型(如java.sql.Date
  3. 反射调用具体的构造函数实例化

BaseTypeTransformer的完整代码:

common-base2/src/main/java/com/gitee/l0km/com4j/basex/BaseTypeTransformer.java · 10km/common-java - 码云 - 开源中国


五、为何不用静态工厂方法?

观察WildcardTyper的设计,可能有读者会问:为什么不像这样提供静态方法?

// 期望的API(但这行不通!)
WildcardType type = WildcardTyper.createWildcard(Number.class, true);

根本原因在于类型擦除:静态方法无法捕获泛型参数的具体类型信息。而通过抽象类的继承模式:

  1. 保留了完整的泛型类型信息
  2. 通过getClass().getGenericSuperclass()获取类型参数
  3. 使TypeToken能准确推断出通配符的边界

六、适用场景分析

  1. 泛型反射操作:在需要解析或生成泛型类型的反射场景
  2. 类型转换系统:构建灵活的类型转换体系
  3. 序列化/反序列化:处理带有通配符的复杂泛型类型
  4. DI容器实现:解析依赖注入时的泛型限定

七、总结与最佳实践

最佳实践建议:

  1. 尽量使用子类模式:如new SubOf<Number>() {}保持类型安全
  2. 结合TypeToken使用:借助Guava的强大类型推断能力
  3. 注意类型边界:明确理解extendssuper的行为差异
  4. 防御式编程:在反射访问时做好类型校验

性能考虑:TypeToken的内部缓存机制保证了重复使用的性能,但在高频场景建议缓存生成的WildcardType实例。

通过本文的代码示例和原理分析,相信读者已经掌握了使用TypeToken优雅处理通配符类型的诀窍。这个技巧在处理复杂泛型系统时显示出极大的威力,值得加入每个Java开发者的工具箱。

八、WildcardTyper 完整代码

package com.gitee.l0km.com4j.basex.reflection;import java.lang.reflect.ParameterizedType;
import java.lang.reflect.WildcardType;import com.google.common.reflect.TypeToken;/*** 用于生成通配符类型(WildcardType)的抽象工具类,支持上界和下界通配符类型<br>* 示例:* <pre>* WildcardTyper<Number> superWildcardTyper = new WildcardTyper<Number>(false) {};* superWildcardTyper.wildcardType ==> ? super Number* WildcardTyper<Number> extendsWildcardTyper = new WildcardTyper<Number>(true) {};* extendsWildcardTyper.wildcardType ==> ? extends Number* </pre>* @param <T> 通配符类型中的边界类型参数,决定通配符类型的上下界基础类型* @author guyadong* @since 4.4.0*/
public abstract  class WildcardTyper<T> {/** 生成的通配符类型实例,如:? super Number */public final WildcardType wildcardType;/** 延迟初始化的TypeToken实例,线程安全 */private volatile TypeToken<?> token;/*** 构造方法,根据subType参数生成对应的通配符类型* * @param subType 通配符类型方向标识:*               - true:生成上界通配符类型(? extends T)*               - false:生成下界通配符类型(? super T)*/@SuppressWarnings("serial")protected WildcardTyper(boolean subType){TypeToken<?> _token;// 根据subType选择创建不同通配符类型的TypeTokenif(subType) {// 创建上界通配符类型TypeToken(Class<? extends T>)_token = new TypeToken<Class<? extends T>>(getClass()) {};}else {// 创建下界通配符类型TypeToken(Class<? super T>)_token = new TypeToken<Class<? super T>>(getClass()) {};}// 从ParameterizedType中提取实际的通配符类型参数this.wildcardType = (WildcardType) ((ParameterizedType) _token.getType()).getActualTypeArguments()[0];}/*** 获取与wildcardType对应的TypeToken实例* * @return 延迟初始化的TypeToken对象,保证线程安全的单例模式*/public TypeToken<?> getToken() {TypeToken<?> _token = this.token;if(null == _token){// 使用双重检查锁定保证线程安全synchronized(wildcardType){_token = this.token;if(null == _token){this.token = _token = TypeToken.of(wildcardType);}}}return _token;}/*** 用于生成下界通配符类型 (? super T) 的抽象基类*/public abstract static class SuperOf<T> extends WildcardTyper<T> {protected SuperOf() {super(false); // 固定调用父类下界构造}}/*** 用于生成上界通配符类型 (? extends T) 的抽象基类 */public abstract static class SubOf<T> extends WildcardTyper<T> {protected SubOf() {super(true); // 固定调用父类上界构造}}
}

BaseTypeTransformer完整代码:common-base2/src/main/java/com/gitee/l0km/com4j/basex/BaseTypeTransformer.java · 10km/common-java - 码云 - 开源中国

WildcardTyperT的单元测试代码:common-base2/src/test/java/com/gitee/l0km/com4j/basex/reflection/WildcardTyperTest.java · 10km/common-java - 码云 - 开源中国


九、参考资料

  1. Guava官方文档
    Guava GitHub仓库
    TypeToken用法详解

  2. Java泛型官方教程
    Oracle Java泛型教程
    Java类型擦除机制

  3. 反射与通配符类型
    Java WildcardType API文档
    ParameterizedType深入解析

  4. 实例项目参考
    BaseTypeTransformer完整源码
    WildcardTyper实现细节

  5. 扩展阅读
    Java类型系统科普
    泛型类型安全最佳实践


希望这些资料能帮助你深入理解Java泛型和反射的奥秘!如果有其他技术问题,欢迎随时交流探讨。 💡

http://www.dtcms.com/wzjs/115175.html

相关文章:

  • 给 小企业 建设网站怎样才能在百度上发布信息
  • 毕业设计代做网站机械临安网站seo
  • 微网站设计企业seo技术是什么意思
  • 伪静态 网站seoer是什么意思
  • 手机怎么制作自己的网站西安网站制作工作室
  • 网站优化推广公司seo实战培训机构
  • 深圳坪山网站建设北京网站seo技术厂家
  • 苏州高端网站制作公司谷歌seo什么意思
  • 精美wordpress模板下载南宁seo推广
  • 简述网站内容管理流程上百度首页
  • 昆明企业建网站多少钱sem是什么的英文缩写
  • 英国做暧小视频网站关键词查询的分析网站
  • 国外购物网站ebay网站模板下载免费
  • 网站推广邮箱怎么做如何开发一个软件平台
  • 个人备案能做什么网站seo公司网站
  • 柴油发电机组网站建设价格外链百科
  • 最专业网站建设哪家好有哪些免费网站可以发布广告
  • 域名做非法网站快速排名优化推广手机
  • 成都网站建设企业seo人人网
  • 厦门seo网站运营推广的方式和渠道
  • b2b网站开发技术文档重庆疫情最新情况
  • 做编程网站有哪些内容免费推广工具有哪些
  • 北京知名网站建设公司企业建站免费模板
  • 个人可以自己做网站吗长沙做搜索引擎的公司
  • 怎么做阿里巴巴国际网站深圳seo
  • python做网站好用吗北京seo代理计费
  • 丛台专业做网站运用搜索引擎营销的案例
  • 泊头市网站建设公司百度电脑版网页版入口
  • 网站显示手机中病毒要按要求做岳阳seo
  • 网站推广排名外包网络营销案例成功案例