Java核心技术 卷1-总结-9

news/2024/5/14 6:27:50/文章来源:https://blog.csdn.net/weixin_42583701/article/details/130233120

Java核心技术 卷1-总结-9

  • 使用异常机制的技巧
  • 为什么要使用泛型程序设计
  • 定义简单泛型类
  • 泛型方法
    • 类型变量的限定
  • 泛型类型的继承规则

使用异常机制的技巧

1.异常处理不能代替简单的测试。 使用异常的基本规则是:只在异常情况下使用异常机制。

2.不要过分地细化异常。
很多程序员习惯将每一条语句都分装在一个独立的try语句块中。
最好将整个任务包装在一个try 语句块中,这样,当任何一个操作出现问题时,整个任务都可以取消。

try {for(i = 0; i < 100; i++) {n = s.pop();out.writeInt(n);}
}
catch (IOException e) {// problem writing to file
}
catch (EmptyStackException e) {// stack was empty 
}

3.利用异常层次结构。
不要只抛出RuntimeException异常。应该寻找更加适当的子类或创建自己的异常类。不要只捕获Thowable异常,否则,会使程序代码更难读、更难维护。

考虑受查异常与非受查异常的区别。已检查异常本来就很庞大,不要为逻辑错误抛出这些异常。

将一种异常转换成另一种更加适合的异常时不要犹豫。例如,在解析某个文件中的一个整数时,捕获NumberFormatException异常,然后将它转换成IOExceptionMySubsystemException的子类。

4.不要压制异常。
在Java中,往往强烈地倾向关闭异常。如果编写了一个调用另一个方法的方法,而这个方法有可能100年才抛出一个异常,那么,编译器会因为没有将这个异常列在throws表中产生抱怨。而没有将这个异常列在throws表中主要出于编译器将会对所有调用这个方法的方法进行异常处理的考虑。因此,应该将这个异常关闭:

public Image loadImage(String s) {try {// code that threatens to throw checked exceptions }catch (Exception e) {} // so there 
}

现在,这段代码就可以通过编译了。除非发生异常,否则它将可以正常地运行。

5.在检测错误时,"苛刻"要比放任更好。
当检测到错误的时候,有些程序员担心抛出异常。在用无效的参数调用一个方法时,返回一个虚拟的数值,还是抛出一个异常,哪种处理方式更好?例如,当栈空时,Stack.pop是返回一个null,还是抛出一个异常?在出错的地方抛出一个EmptyStackException 异常要比在后面抛出一个NullPointerException异常更好。

6.不要羞于传递异常。
很多程序员都感觉应该捕获抛出的全部异常。如果调用了一个抛出异常的方法,例如,FilelnputStream构造器或readLine方法,这些方法就会本能地捕获这些可能产生的异常。其实,传递异常要比捕获这些异常更好:

public void readStuff(String filename)throws IOException { // not a sign of shame! InputStream in = new FileInputStream(filename);
}

规则5、6可以归纳为“早抛出,晚捕获”。

为什么要使用泛型程序设计

泛型程序设计(Generic programming)意味着编写的代码可以被很多不同类型的对象所重用。例如,我们并不希望为聚集String和File对象分别设计不同的类。实际上,也不需要这样做,因为一个ArrayList类可以聚集任何类型的对象。这是一个泛型程序设计的实例。

定义简单泛型类

一个泛型类(generic class)就是具有一个或多个类型变量的类。以Pair类作为例子:

public class Pair<T> {private T first;private T second;public Pair() { first=null; second=null; }public Pair(T first,T second) { this.first = first; this.second = second; }public T getFirst(){ return first; }public T getSecond() { return second; }public void setFirst(T newValue){ first m newValue; }public void setSecond(T newValue){ second = newValue; }
}

Pair类引入了一个类型变量T,用尖括号<>括起来,并放在类名的后面。 泛型类可以有多个类型变量。例如,可以定义Pair类,其中第一个域和第二个域使用不同的类型:

public class Pair<T,U> {...}

类定义中的类型变量指定方法的返回类型以及域和局部变量的类型。 例如,

  private T first;// uses the type variable

类型变量使用大写形式。在 Java库中,使用变量E表示集合的元素类型,KV分别表示表的关键字与值的类型。T(需要时还可以用临近的字母US)表示“任意类型”。

用具体的类型替换类型变量就可以实例化泛型类型, 例如:

Pair<String>

可以将结果想象成带有构造器的普通类:

Pair<String>()
Pair<String>(String, String)

和方法:

String getFirst()
String getSecond()
void setFirst(String)
void setSecond(String)

换句话说,泛型类可看作普通类的工厂。

泛型方法

还可以定义带有类型参数的简单方法。

class ArrayAlg {public static <T> T getMiddle(T... a) {return a[a.length / 2];}
}

这个泛型方法是在普通类中定义的,而不是在泛型类中定义的。注意,类型变量放在修饰符(这里是public static)的后面,返回类型的前面。

泛型方法可以定义在普通类中,也可以定义在泛型类中。当调用一个泛型方法时,在方法名前的尖括号中放入具体的类型

String middle = ArrayAlg.<String>getMiddle("John","Q.", "Public");

类型变量的限定

有时,类或方法需要对类型变量加以约束。下面是一个典型的例子。我们要计算数组中的最小元素:

class ArrayAlg {public static <T> T min(T[] a) { // almost correct if (a == null || a.length == 0) {return null;}T smallest = a[0];for (int i = 1; i < a.length; i++) {if(smallest.compareTo(a[i])>0) { smallest = a[i];}}return smallest;}
}

但是,这里有一个问题。min方法的代码内部,变量smallest类型为T,这意味着它可以是任何一个类的对象。怎么才能确信T所属的类有compareTo方法呢?
解决这个问题的方案是将T限制为实现了Comparable接口(只含一个方法compareTo的标准接口)的类。可以通过对类型变量T设置限定(bound) 实现这一点:

public static <T extends Comparable> T min(T[] a)... 

现在,泛型的min方法只能被实现了Comparable接口的类(如 String、LocalDate 等)的数组调用。
在此为什么使用关键字extends而不是implements?毕竟,Comparable是一个接口。

<T extends BoundingType>

表示T应该是绑定类型的子类型(subtype)。T和绑定类型可以是类,也可以是接口。 选择关键字 extends 的原因是更接近子类的概念。
一个类型变量或通配符可以有多个限定,例如:

T extends Comparable & Serializable

限定类型用“&”分隔,而逗号用来分隔类型变量。
在Java的继承中,可以根据需要拥有多个接口超类型,但限定中至多有一个类。如果用一个类作为限定,它必须是限定列表中的第一个。

泛型类型的继承规则

考虑一个类和一个子类,如Employee和Manager。Pair不是Pair的一个子类,下面的代码将不能编译成功:

Manager[] topHonchos = . . .;
Pair<Employee> result = ArrayAlg.minmax(topHonchos);// Error

minmax 方法返回Pair,而不是Pair,并且这样的赋值是不合法的。无论S与T有什么联系。
在这里插入图片描述

这一限制看起来过于严格,但对于类型安全非常必要。假设允许将Pair转换为Pair。考虑下面代码:

Pair<Manager> managerBuddies = new Pair<>(ceo, cfo);
Pair<Employee> employeeBuddies = managerBuddies; // illegal, but suppose it wasn't 
employeeBuddies.setFirst(lowlyEmployee);

显然,最后一句是合法的。但是employeeBuddiesmanagerBuddies引用了同样的对象。现在将cfo和一个普通员工组成一对,这对于Pair<Manager>来说应该是不可能的。

注意∶必须注意泛型与Java数组之间的重要区别。可以将一个Manager[]数组赋给一个类型为Employee[]的变量:

Manager[] managerBuddies = { ceo, cfo };
Employee[] employeeBuddies = managerBuddies; // OK

然而,数组带有特别的保护。如果试图将一个低级别的雇员存储到employeeBuddies[0],虚拟机将会抛出ArrayStoreException异常。

永远可以将参数化类型转换为一个原始类型。例如,Pair是原始类型Pair的一个子类型。在与遗留代码衔接时,这个转换非常必要。
但转换成原始类型之后会产生类型错误。比如下面这个示例:

Pair<Manager> managerBuddies = new Pair<>(ceo, cfo);
Pair rawBuddies = managerBuddies;// OK
rawBuddies.setFirst(new File("...."));// only a compile-time warning

当使用getFirst获得外来对象并赋给Manager变量时,与通常一样,会抛出 ClassCastException异常。这里失去的只是泛型程序设计提供的附加安全性。

泛型类可以扩展或实现其他的泛型类。 就这一点而言,与普通的类没有什么区别。例如,ArrayList<T>类实现List<T>接口。这意味着,一个ArrayList<Manager>可以被转换为一个List<Manager>。但是,,一个 ArrayList<Manager>不是一个ArrayList<Employee>List<Employee>
在这里插入图片描述

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

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

相关文章

人机交互有哪些SCI期刊推荐? - 易智编译EaseEditing

以下是几个人机交互领域的SCI期刊推荐&#xff1a; ACM Transactions on Computer-Human Interaction (ACM TOCHI)&#xff1a; 由ACM&#xff08;Association for Computing Machinery&#xff09;出版的人机交互领域的顶级期刊之一&#xff0c;发表关于计算机和人之间相互作…

简单聊下HBase

大家好&#xff0c;我是易安&#xff01; Google发表了三篇论文&#xff0c;即GFS、MapReduce和BigTable&#xff0c;被誉为“三驾马车”&#xff0c;开启了大数据时代。今天我们来聊一下BigTable对应的NoSQL系统HBase&#xff0c;看看它是如何处理海量数据的。 在计算机数据存…

客户体验的重要性和企业发展的紧密联系

近年来&#xff0c;随着企业数字化转型的加速&#xff0c;客户服务的意义越来越被人们所重视。客户服务的质量不仅直接影响到客户满意度和忠诚度&#xff0c;而且会间接影响到企业的品牌口碑和市场竞争力。然而&#xff0c;目前市面上的很多企业帮助中心搭建平台&#xff0c;可…

Point cloud tools for Matlab(点云学习工具)

Point cloud tools for Matlab (tuwien.ac.at)https://www.geo.tuwien.ac.at/downloads/pg/pctools/pctools.html#PointCloud_class 下载&#xff1a;Download Matlab Code 添加路径 addpath(genpath(D:\MyMatlabCode\pointCloudTools)); pc pointCloud(Lion.xyz); pc.plot…

redis入门必会知识

Redis基础知识目录 5、sortedSet 文章目录 系列文章目录前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 前言 一、redis是什么&#xff1f; Redis&#xff08;Remote Dictionary Server )&#xff0c;即远程字典服务 ! 是一个开源的使用ANSI C语言编写…

Python 查看数据常用函数

Python 查看数据常用函数&#xff08;以 iris 数据集为例&#xff09; 1、查看前后几行数据&#xff1a;head 和 tail2、查看数据基本信息&#xff1a;info3、查看数据统计信息&#xff1a;describe 查看数据可以用很多函数&#xff0c;这里就挑选几个最常用的进行简单展示&…

除了学历,你更需要有能力

遥想当年&#xff0c;家里培养出一个大学生&#xff0c;是多荣耀的事&#xff01;可现今却处于一个比较尴尬的状态。 为什么大学生贬值得这么厉害&#xff1f;其实大学生之所以会不值钱不外乎三大原因&#xff1a;量大、与企业需求不匹配、质量差。 高校扩招下&#xff0c;大…

分布式系统反向代理设计与正向代理

反向代理与正向代理分析 代理服务器&#xff1a;位于发起请求的客户端与原始服务器端之间的一台跳板服务器&#xff0c;代理服务器分为正向代理服务器和反向代理服务器 正向代理 &#xff1a;代理客户端&#xff0c;隐藏了真实的请求客户端&#xff0c;服务端不知道真实的客户…

数据库系统概论--第五章课后习题

1.什么是数据库的完整性&#xff1f; 答&#xff1a;数据库的完整性是指数据的正确性和相容性。 2. 数据库的完整性概念与数据库的安全性概念有什么区别和联系&#xff1f; 答&#xff1a; 数据的完整性和安全性是两个不同的概念,但是有一定的联系。前者是为了防止数据库中存…

TortoiseSVN使用-授权访问

文章目录 3.4.6 授权访问 3.4.6 授权访问 总结&#xff1a; 如果是匿名访问&#xff08;就是不用输入用户名密码的访问方式&#xff09;&#xff0c;请只开启anon-access write如果授权访问&#xff0c;请先设置anon-access none&#xff0c;然后打开3个&#xff1a;auth-a…

JDBC操作数据库

数据库介绍 数据库是一种存储结构&#xff0c;允许使用各种格式输入、处理和检索数据&#xff0c;不必再每次需要数据时重新输入。当前比较流行的数据库主要有MySQL、Oracle、SQL Server等 使用JDBC操作数据库&#xff0c;SQL语句是比不可少的&#xff0c;SQL是一种结构化查询…

自媒体必备素材库,免费、商用,赶紧马住~

自媒体经常需要用到各类素材&#xff0c;本期就给大家安利6个自媒体必备的素材网站&#xff0c;免费、付费、商用都有&#xff0c;建议收藏起来~ 1、菜鸟图库 https://www.sucai999.com/video.html?vNTYwNDUx 菜鸟图库可以找到设计、办公、图片、视频、音频等各种素材。视频素…

集群聊天服务器项目(三)——负载均衡模块与跨服务器聊天

负载均衡模块 为什么要加入负载均衡模块 原因是&#xff1a;单台服务器并发量最多两三万&#xff0c;不够大。 负载均衡器 Nginx的用处或意义**&#xff08;面试题&#xff09;** 把client请求按负载算法分发到具体业务服务器Chatserver能和ChatServer保持心跳机制&#xf…

深入浅出JS定时器:从setTimeout到setInterval

前言 当谈到 JavaScript 编程语言最基本的概念时&#xff0c;定时器就是一个必须掌握的知识点。在编写网站时&#xff0c;你经常会遇到需要在一定时间间隔内执行一些代码的情况。这时候&#xff0c;JavaScript 定时器就可以派上用场了。 什么是定时器&#xff1f; JS 定时器是…

@Configuration 和 @Component 注解的区别

一句话概括就是 Configuration 中所有带 Bean 注解的方法都会被动态代理&#xff0c;因此调用该方法返回的都是同一个实例。 理解&#xff1a;调用Configuration类中的Bean注解的方法&#xff0c;返回的是同一个示例&#xff1b; 而调用Component类中的Bean注解的方法&#x…

JavaEE-一文了解IP协议与IP地址

目录 IP协议什么是IP地址IP地址的组成动态分配IPNAT机制(网络地址转换) IP协议 IP协议是不可靠、无连接的 不可靠:表示IP协议不能保证IP数据报能成功的到达目的地。IP仅提供传输服务&#xff0c;任何可靠性的要求都必须由上层来提供&#xff08;如TCP&#xff09;。如果传输过…

【Cpp】手撕搜索二叉树(KV模型)

文章目录 二叉搜索树的应用搜索二叉树(KV模型)代码:二叉搜索树的性能分析 二叉搜索树的应用 K模型&#xff1a;K模型即只有key作为关键码&#xff0c;结构中只需要存储Key即可&#xff0c;关键码即为需要搜索到的值。 比如&#xff1a;给一个单词word&#xff0c;判断该单词是…

QGIS--开发OpenSCENARIO动态场景(三)--制作动态场景

一、添加scenario&#xff0c;carla的环境变量 export CARLA_ROOT/path/to/your/carla/installation export SCENARIO_RUNNER_ROOT/path/to/your/scenario/runner/installation export PYTHONPATH$PYTHONPATH:${CARLA_ROOT}/PythonAPI/carla/dist/carla-<VERSION>.egg ex…

Java核心技术 卷1-总结-12

Java核心技术 卷1-总结-12 具体的集合链表数组列表 具体的集合 下表中除了以 Map结尾的类之外&#xff0c; 其他类都实现了 Collection 接口&#xff0c;而以 Map结尾的类实现了 Map 接口。 集合类型描述ArrayList一种可以动态增长和缩减的索引序列LinkedList一种可以在任何位…

MySql知识

架构分层 模块详解 Connector&#xff1a;支持各种语言和SQL的交互&#xff0c;如PHP&#xff0c;Python&#xff0c;JAVA JDBC Management Services & Utilities&#xff1a;系统管理和控制工具&#xff0c;包括备份恢复&#xff0c;MySQL复制&#xff0c;集群等 Connec…