一个程序开发出来之后,无论是用户还是程序员,都希望它稳定地运行,然而程序毕竟是人写的,人无完人哪能不犯点错误呢?就算事先考虑得天衣无缝,揣着一笔巨款跑去岛国买了栋抗震性能良好的海边别墅,谁料人算不如天算,碰到猴年马月遇上了一场大海啸,整个别墅被冲到山上去了.计算机程序也是如此,不管是人为的错误,还是意外的风险,都会导致程序在运行时异常退出.引起程序异常的原因多种多样,就已经介绍过的知识点而言,主要有这么几种可能发生异常的情况:数学运算异常.数组越界异常.字符串与日期格式异常.空指针异常.类型转换…
每个程序员都希望自己的程序稳定运行,不要隔三岔五出什么差错,可是程序运行时冒出来的各种异常着实烦人,令人不胜其扰.虽然可以在代码中补上try/catch语句捕捉异常,但毕竟属于事后的补救措施.与其后知后觉地亡羊补牢,不如一开始就未雨绸缪,只要防患于未然,必能收到事半功倍的成效.就编码时的常见异常而言,绝大多数异常都能通过适当的校验加以规避,也就是事先指定可让程序正常运行的合法条件,只有条件满足才开展业务逻辑处理,否则进行失败情况的处理.这样用于异常捕捉的try/catch语句便转换为了条件分支的…
不管是基本的char字符型,还是包装字符类型Character,它们的每个变量只能存放一个字符,无法满足对一串字符的加工.为了能够直接操作一连串的字符,Java设计了专门的字符串类型String,该类型允许保存一整串字符,并对字符串进行各种处理.字符串类型不属于基本类型,它的用法与包装类型更为接近.例如给字符串变量赋初始值,就有多达四种的赋值形式(包装类型只有三种赋值),分别介绍如下:1.被双引号包裹着的字符串,可直接用等号赋值给字符串变量,代码示例如下: // 第一种方式:用双引号把字符串括起…
前面介绍的几种异常(不包含错误),编码的时候没认真看还发现不了,直到程序运行到特定的代码跑不下去了,程序员才会恍然大悟:原来这里的代码逻辑有问题.像这些在运行的时候才暴露出来的异常,又被称作“运行时异常”,与之相对的另一类异常叫做“非运行时异常”.所谓非运行时异常,指的是在编码阶段就被编译器发现这里存在潜在的风险,需要开发者关注并加以处理.比如把某个字符串转换成日期类型,用到了SimpleDateFormat实例的parse方法,倘若按照常规方式编码,则编译器会在parse这行提示代码错误,并给…
早在介绍多态的时候,曾经提到公鸡实例的性别属性可能被篡改为雌性,不过面向对象的三大特性包含了封装.继承和多态,只要把性别属性设置为private私有级别,也不提供setSex这样的性别修改方法,那么性别属性就被严严实实地封装了起来,不但外部无法修改性别属性,连公鸡类的子类都无法修改.如此一来,公鸡实例的性别属性可谓防护周全,压根不存在被篡改的可能性.但是Java给面向对象留了个后门,也就是反射技术,利用反射技术竟然能够攻破封装的防护网,使得篡改私有属性从理想变成了现实,赶紧来看看反射技术是怎样做…
由于泛型存在某种不确定的类型,因此很少直接运用于拿来即用的泛型类,它更经常以泛型接口的面目出现.例如几种基本的容器类型Set.Map.List都被定义为接口interface,像HashSet.TreeMap.LinkedList等等只是实现了对应容器接口的具体类罢了.泛型的用途各式各样,近的不说,远的如数组工具Arrays的sort方法,它在排序时用到的比较器Comparator就是个泛型接口.别看Comparator.java的源码洋洋洒洒数百行,其实它的精华部分仅仅下列寥寥数行: //数组…
清单作为一组数据的有序队列,它在组织形式上与数组有着某些异曲同工之处,数组有专门的数组工具Arrays来进行加工操作,照理清单也应该配备对应的清单工具.当然容器这个大家族确实拥有自己的容器工具Collections,不过数组工具Arrays也隐藏着一个清单方法,它便是asList,该方法类似数组的初始赋值,同样支持把括号内部的一系列数据直接转为清单对象.前面介绍泛型类和泛型接口的时候,就利用Arrays.asList给某个清单实例进行了初始化赋值,不过调用asList得到的数组大小是固定的,无法…
通过前面几篇文章的学习,大家应能掌握几种容器类型的常见用法,对于简单的增删改和遍历操作,各容器实例都提供了相应的处理方法,对于实际开发中频繁使用的清单List,还能利用Arrays工具的asList方法给清单对象做初始化赋值,另外提供了专门的Collections工具进行排序.求最大元素.求最小元素等操作.那么涉及到更加复杂的数据处理,游荡如何有针对性地筛选和进一步加功能?依次遍历目标容器,对所有元素逐个加以分析判断,并酌情将具体数据调整至满意的状态,这种千篇一律的业务流程固然能够解决问题,可惜…
前面介绍的几种异常,其实都存在这样那样的逻辑问题,属于程序员的编码手误.还有一大类系统错误,表面上看不出什么问题,但是程序仍然运行不下去,兹举二例说明.第一个例子且看下列的测试代码: // 测试内存溢出错误:程序需要的内存超过了最大的堆内存配置 private static void testUnlimitedString() { String str = "Hello world"; String result = getUnlimitedString(str); // 获取无限大小…
前面在介绍清单用法的时候,讲到了既能使用for循环遍历清单,也能通过stream流式加工清单.譬如从一个苹果清单中挑选出红苹果清单,采取for循环和流式处理都可以实现.下面是通过for循环挑出红苹果清单的代码例子: // 通过简单的for循环挑出红苹果清单 private static void getRedAppleWithFor(List<Apple> list) { List<Apple> redAppleList = new ArrayList<Apple>()…