java泛型程序设计——Varargs 警告+不能实例化类型变量

【0】README

0.1) 本文描述+源代码均 转自 core java volume 1, 旨在理解 java泛型程序设计 的 Varargs 警告+不能实例化类型变量 的知识;


【1】 Varargs 警告

1.1)一个相关问题: 向参数个数可变的方法传递一个泛型类型的实例;

  • 1.1.1)考虑以下方法, 它的参数个数是可变的:
public static<T> void addAll(Collection<T) coll, T...ts)
{......
}
  • 1.1.2)应该记得, 实际上参数ts 是一个数组, 包含所有实参, 考虑以下调用:
Collection<Pair<String>> table = ......;
Pair<String> pair1 = ....;
Pair<String> pair2 = ....;
addAll(table, pair1, pair2);
  • 1.1.3)为了调用上述方法: java 虚拟机必须建立一个 Pair 数组, 这就违反了前面的规则, 不过, 对于这种case , 你只会得到一个警告, 而不是 错误;

1.4)可以采用以下两种方法来抑制这种警告(Methods):(解决方法)

  • M1)一种方法是 为 包含 addAll 调用的方法增加 标注
@SuppressWarnings("unchecked");
  • M2)在java se 7中, 还可以用 @SafeVarargs 直接标注addAll 方法:
@SafeVarargs
public static <T> void addAll(Collection<T> coll, T...ts);
  • 现在就可以用 泛型类型来调用这个方法了;

Annotation)

  • A1)可以使用 @SafeVarargs 标注来消除创建泛型数组的有关限制, 方法如下:
@SafeVarargs
static <E> E[] array(E... array)
{return array;
}
  • A2)现在可以调用:
Pair<String>[] table = array(pair1, pair2);
  • 这看起来方便, 不过隐藏着危险, 如下代码:
Object[] objarray = table;
objarray[0] = new Pair<Employee>();
  • 能顺利运行而不会出现 ArrayStoreException 异常 (因为数组存储只会检查擦除的类型), 但在处理 table[0] 时 你会在别处得到一个异常;

【2】不能实例化类型变量

2.1)不能使用像 new T(…), new T[…] 或 T.class 这样的表达式中的类型变量。

  • 2.1.1)看个荔枝:(下面的 Pair 构造器就是非法的)
public Pair()
{first = new T();second = new T(); // ERROR
}
  • 2.1.2)类型擦除将T 改变成 Object, 而且, 本意肯定不希望调用 new Object()。
  • 2.1.3)但是可以通过反射调用 Class.newInstance 方法来构造泛型对象:
然而,我们却不能调用: first = T.class.newInstance();//ERROR
  • 2.1.4)因为, 表达式 T.class 是不合法的, 必须像下面这样设计 API 以便可以支配Class 对象:
public static<T> Pair<T> makePair(Class<T> cl)
{try{ return new Pair<>(c1.newInstance(), c1.newInstance()) }catch(Exception ex) {return null;}
}
  • 2.1.5)以上方法可以按照下列方式调用:
Pair<String>p = Pair.makePair(String.class);
  • Attention) Class 类本身就是泛型, 如, String.class 是一个 class《String》 的实例(事实上, 它是唯一的实例)。 因此, makePair 方法能够推断出 pair 的类型;
  • 2.1.6) 不能构造一个 泛型数组:
public  static <T extends Comparable> T[] minmax(T[] a) { T[] mm = new T[2]; ...} //ERROR
  • 类型擦除会让这个方法永远构造 Object[2]数组;

2.2)如果数组仅仅是作为一个类的私有实例域, 就可以将这个数组声明为 Object[], 并且在获取元素时进行类型转换。

  • 2.2.1)看个荔枝: 如 ArrayLIst 可以这样实现:
public class ArrayList<E>
{private Object[] elements;...@SuppressWarnings("unchecked")public E get(int n){return (E) elements[n]; //获取元素时进行类型转换}pubic void set(int n, E e){elements[n] =e;}
}
  • 2.2.2)实际的实现没有这么清晰:
public class ArrayList<E>
{paivate E[] elements;...public ArrayList(){ elements = (E[])new Object[0]; }
}
  • 2.2.3)这里, 强制类型转换 E[] 是一个假想, 而类型 擦除使其无法察觉;

2.3)由于 minmax方法 返回 T[] 数组, 使得这一技术无法施展, 如果掩盖这个类型会有运行时错误。假设实现代码:

public static <T extends Comparable> T[] minmax(T...a)
{Object[] mm = new Object[2];...reutrn (T[]) mm;
}

2.4)调用String[] ss = minmax(“tom”, “dick”, “Harry”);
对上述代码的分析(Analysis):

  • A1)编译时不会有任何警告。 但Object[] 引用赋给 String[] 变量时, 将会发生 ClassCastException 异常;
  • A2)在这种case下, 利用反射,调用 Array.newIntance;
public static <T extemds Comparable> T[] minmax(T... a)
{T[] mm = (T[])mm.newInstance(a.getClass().getComponentType(), 2);
}    
  • A3)ArrayList 类的toArray方法就没有这么幸运了。 它需要生成一个 T[] 数组, 但没有成分类类型。 因此, 有下面两种不同的形式:
Object[] toArray();
T[] toArray(T[] result);
  • 第二个方法接收一个数组参数。 如果数组足够大, 就是用这个数组。 否则, 用result 的成分类型构造一个足够大的 新数组;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/331813.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

rabbitmq怎么停止_Windows环境下RabbitMQ的启动和停止命令

Windows环境下RabbitMQ的启动和停止命令原创lockie_zou 最后发布于2018-05-24 15:34:21 阅读数 36514 收藏展开首先windows下安装好了erlang和rabbitmq。如下地址同时下载和安装&#xff1a;Erlang&#xff1a;http://www.erlang.org/download.htmlRabbitMQ &#xff1a;http:…

elk入门_ELK堆栈入门

elk入门朋友不允许朋友写用户身份验证。 厌倦了管理自己的用户&#xff1f; 立即尝试Okta的API和Java SDK。 数分钟之内即可在任何应用程序中对用户进行身份验证&#xff0c;管理和保护。 好的设计原则要求微服务架构是可观察的&#xff0c;并提供集中的监视工具。 该工具使开…

java泛型程序设计——泛型类的静态上下文中类型变量无效+不能抛出或捕获泛型类的实例

【0】README 0.1&#xff09; 本文描述源代码均 转自 core java volume 1&#xff0c; 旨在理解 java泛型程序设计 的 泛型类的静态上下文中类型变量无效不能抛出或捕获泛型类的实例 的知识&#xff1b; 【1】泛型类的静态上下文中类型变量无效 1.1&#xff09;不能在静态域或…

android ril.java_Android RIL学习

1.Android RIL概念Android RIL是基于telephony服务和raido硬件层的抽象层。Android的rild库是介于HAL接口与baseband modem之间&#xff0c;它提供了语音、数据、短信、SIM卡管理以及STK应用的功能。它把标准的GSM27.007中常用的如dial这些做主动请求的操作称之为request&#…

netty java_Netty Java快速指南

netty java使用Okta的身份管理平台轻松部署您的应用程序 使用Okta的API在几分钟之内即可对任何应用程序中的用户进行身份验证&#xff0c;管理和保护。 今天尝试Okta。 Netty是一个无阻塞输入/输出&#xff08;NIO&#xff09;框架&#xff0c;它使开发低级网络服务器和客户端…

java泛型程序设计——注意擦除后的冲突

【0】README 0.1&#xff09; 本文描述源代码均 转自 core java volume 1&#xff0c; 旨在理解 java泛型程序设计 的 注意擦除后的冲突 的知识&#xff1b; 1.1&#xff09;当泛型类型被 擦除时&#xff0c; 无法创建引发冲突的条件。 1.1.1&#xff09;看个荔枝&#xff…

java的Swing里怎么new一条线_java – 在JFrame上绘制一条线

我正在尝试使用图形2D绘制一条线,但然后该线出现在所有的线上JFrame中的其他组件因此使它们不可见.我该如何解决这个问题&#xff1f;这是代码&#xff1a;import javax.swing.*;import java.awt.*;import java.awt.geom.*;class Success extends JFrame{public Success(){JPan…

java –cp_Java –缺少字体–崩溃的应用程序!

java –cpEclipse MAT和Heaphero都是分析大型堆转储的流行Java工具。 最近&#xff0c;当我们尝试在Eclipse MAT中分析堆转储文件时遇到了一个有趣的问题。 工具因缺少字体crash而崩溃。 我们认为我们将与您分享发现的结果。 CompositeStrike.getStrikeForSlot&#xff08;&am…

java泛型程序设计——泛型类型的继承原则

【0】README 0.1&#xff09; 本文描述源代码均 转自 core java volume 1&#xff0c; 旨在理解 java泛型程序设计 的 泛型类型的继承原则 的知识&#xff1b; 【1】泛型类型的继承原则相关 1.1&#xff09;考虑一个类 Employee 和一个Employee子类 Manger &#xff0c; 问&a…

用java代码写美国时间_如何衡量Java代码所用的时间?

本问题已经有最佳答案&#xff0c;请猛点这里访问。我需要分析Java中的一些算法的复杂性。为此&#xff0c;我计划提供大量的输入&#xff0c;并测量Java实现所花费的时间。检查某些代码行之间的时间最精确和准确的方法是什么&#xff1f;我需要精确到毫秒…不完全是&#xff0…

reactor使用方法_Project Reactor展开方法

reactor使用方法最近&#xff0c;我的一位同事向我介绍了Project Reactor类型的expand运算符&#xff0c;在这篇文章中&#xff0c;我想介绍几种使用它的方式。 展开分页结果 考虑在名为City的模型上基于Spring Data的存储库&#xff1a; import org.springframework.data.jpa…

java泛型程序设计——通配符类型+通配符的超类型限定

【0】README 0.1&#xff09; 本文描述源代码均 转自 core java volume 1&#xff0c; 旨在理解 java泛型程序设计 的 通配符类型通配符的超类型限定 的知识&#xff1b; 【1】通配符类型相关 1.1&#xff09;通配符类型&#xff1a; Pair < ? extends Employee> 表示…

java 延迟初始化_Java并发编程——延迟初始化占位类模式

——仅作笔记使用&#xff0c;内容多摘自《java并发编程实战》在并发编程中&#xff0c;如果状态变量仅在单个线程中初始化和使用&#xff0c;自然是线程安全的&#xff0c;但一旦涉及到线程间的数据交互&#xff0c;如何声明一个用于多线程的单例状态变量才是安全的呢&#xf…

log4j 程序日志_Log4j错误–减慢您的应用程序

log4j 程序日志最近&#xff0c;我们正在对流行的SaaS应用程序进行故障排除。 该应用程序间歇性地变慢。 要从问题中恢复&#xff0c;必须重新启动应用程序。 在高流量期间&#xff0c;此应用有时会变慢。 有时在交通繁忙时也是如此。 没有凝聚力模式。 这类应用程序变慢并重新…

java泛型程序设计——无限定通配符+通配符捕获

【0】README 0.1&#xff09; 本文描述源代码均 转自 core java volume 1&#xff0c; 旨在理解 java泛型程序设计 的 无限定通配符通配符捕获 的相关知识&#xff1b; 【1】无限定通配符相关 1.1&#xff09;无限定通配符&#xff1a; 如Pair< ?>&#xff1b; 1.1.1…

java方法2数据求和_Leet Code 2 Add Two Numbers - 链表表示的两个数求和 - Java

给定两个链表表示的非负整数&#xff0c;每个节点存储一位数&#xff0c;各位数以逆序存储。将两个数相加&#xff0c;以链表形式返回结果。例如&#xff1a;输入&#xff1a;(2 -> 4 -> 3) (5 -> 6 -> 4)输出&#xff1a;7 -> 0 -> 8/*** Definition for s…

java泛型程序设计——反射和泛型

【0】README 0.1&#xff09; 本文描述源代码均 转自 core java volume 1&#xff0c; 旨在理解 java泛型程序设计 的 反射和泛型 的相关知识&#xff1b; 【1】反射和泛型相关 1.1&#xff09;现在&#xff0c; Class类是泛型的&#xff0c; 如 String.class 实际上是一个 C…

kafka异步发送数据_在Kafka上异步发送数据

kafka异步发送数据对于一个项目&#xff0c;我试图记录用户的基本交易&#xff0c;例如添加和删除一个项目以及多种类型的项目&#xff0c;并为每笔交易向kafka发送一条消息。 日志机制的准确性不是至关重要的&#xff0c;在kafka服务器停机的情况下&#xff0c;我不希望它阻止…

java按钮权限控制_详解Spring Security 中的四种权限控制方式

Spring Security 中对于权限控制默认已经提供了很多了&#xff0c;但是&#xff0c;一个优秀的框架必须具备良好的扩展性&#xff0c;恰好&#xff0c;Spring Security 的扩展性就非常棒&#xff0c;我们既可以使用 Spring Security 提供的方式做授权&#xff0c;也可以自定义授…

aws 数据库迁移_AWS Loft的数据库周

aws 数据库迁移这是我的笔记&#xff1a; https://databaseweekoctober2019sf.splashthat.com AWS上的数据库&#xff1a;合适工作的合适工具 在许多此类谈话中&#xff0c;我并没有做过深刻的记录。 我正在关注重点。 PostgreSQL排在MySQL之后。 AWS上8种类型的数据库&…