ICode9

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

Java中的未绑定泛型返回类型

2019-07-06 00:03:03  阅读:194  来源: 互联网

标签:java api-design generics


我正在玩有关构建Java API的一些想法,今天我花了一些时间思考这段代码:

public <T> T getField1(Class<?> type, Class<T> retvalType, String fieldName) {
  Object retval = ...; // boring reflection code - value could be dog, could be duck
  return retvalType.cast(retval); // cast to expected - exception is raised here
}

// usage - we manually repeat the LHS type as a parameter
int foo = getField(o, Integer.class, "foo");

这就是我通常编写API的方法,因为他认为指定retvalType会给我额外的类型安全性.但是呢?

因为我们有反射,所以retval类型是未知的.仅当retvalType为非泛型时,第二行上的强制转换才能可靠地捕获类型不匹配.另一方面,即使我们不进行这种显式转换,Java运行时也会在将它设置为变量时转换泛型结果 – 换句话说,如果我们将上面的代码重写为:

public <T> T getField2(Class<?> type, String fieldName) {
  return ...; // boring reflection code - the value type will be checked when we assign it
}

// usage - exception is raised at the next line if types don't match
int foo = getField(o, "foo");

后一个代码的优点是使用更紧凑,我们不必重复自己.缺点是类型转换异常来自非显而易见的地方(在调用站点没有显式转换),但我开始认为这没关系 – 通过指定类型文字,我们只重复我们已经知道的,但最终由于反思,程序的稳健性仍然无法保证.

谁能说出为什么第一个片段比第二个更好?

编辑1:

一个论点是,通过将期望的类型作为参数,我们可以满足在不改变API的情况下进行非平凡强制的需要.

例如,查找字段可以是Date类型,但我们可能请求long,可以通过执行date.getTime()在内部进行转换.这对我来说似乎有些牵强,并且存在混合责任的风险.

另一方面,不传递类型限制了输入依赖性,这使得API对更改更加健壮. (提示’信息隐藏’,’不稳定指标’等).

解决方法:

在与@shmosel的对话中,我们发现,当LHS类型是泛型类型时,第二个版本所依赖的运行时强制转换不一定会发生.

例如,考虑代码:

class Foo<T> {
  void a1(Object o) {
    // forces to be explicit about the chance of heap polution
    @SuppressWarning("unchecked")
    Set<String> a = (Set<String>) getField1(o, Set.class, "foo");
    T c = (T) getField1(o, Set.class, "foo"); // guaranteed not to compile
  }

  void a2(Object o) {
    // implicit chance of heap polution in case of Set<Date>
    Set<String> a = (Set<String>) getField2(o, "foo");
    T c = getField2(o, "foo"); // will succeed even if foo is Date
  }
}

换句话说,通过在getField()方法中进行转换,我们得到了一个硬保证,即该值是指定类的,即使它没有被使用,也没有分配给Object变量(通常在动态语言和反思图书馆).

标签:java,api-design,generics
来源: https://codeday.me/bug/20190705/1391894.html

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

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

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

ICode9版权所有