- 博客(134)
- 资源 (1)
- 收藏
- 关注
原创 11.76-11.78 使用序列化
1.覆盖readObject()检查反序列化对象的有效性,以防止安全攻击。readObject()可视为一个隐藏的构造函数。在此方法里不要直接或间接的调用对象的可覆盖的方法(因为执行这些可覆盖的方法时,子类对象的状态可能还未初始化)注:原书有说明如何使用序列化注入不安全的对象 2.对于对象控制,优先使用枚举类代替readResolve()方法。比如使用枚举实现单例模式注:...
2013-09-10 11:47:29
125
原创 11.75 考虑使用自定义序列化数据格式
对象的序列化机制相当于提供了另一种方式创建对象。也可以理解为如果对象支持序列化,相当于对象声明了一个隐藏的构造函数。如果对象的类结构改变了,那么以前的序列化数据进行反序列化可能导致错误。 默认的序列化将写入对象的“物理内容”。包括对象本身,以及以此对象为根节点,所能访问的所有引用对象。使用默认序列化可能导致的问题有: 1.序列化数据与序列化对象内部引用的对象的API耦合在一起,...
2013-09-10 10:42:17
170
原创 11.75 考虑使用自定义序列化数据格式
改变了,那么以前的序列化数据进行反序列化可能导致错误。 默认的序列化将写入对象的“物理内容”。包括对象本身,以及以此对象为根节点,所能访问的所有引用对象。使用默认序列化可能导致的问题有: 1.序列化数据与序列化对象内部引用的对象的API耦合在一起,如果引用对象的API改变,那么反序列化时可能出现错误 2.序列化引用对象将会消耗额外的空间(序列化数据)和时间(序列化过程) 3.在序列化过程中,可能导致内存溢出 因此建议使用自定义序列化,仅写入对象的“逻辑内容”,基本原则
2013-09-10 10:42:17
116
原创 使用Maven发布项目
本文介绍如何使用maven发布项目到SVN,进而对项目进行版本控制。本文相关概念参考自《Maven最佳实践:版本管理》 使用的开发环境如下(需要确定在命令行窗口里可以运行svn --version; mvn --version命令):maven3.0.5 TortoiseSVN-1.8.1安装时需要勾选安装svn命令行工具SVN仓库(SvnRepo)...
2013-08-23 14:16:36
131
原创 11.74 谨慎的使用序列化
Java的序列机制:序列化把JVM里的对象转换为字节数据,此数据可传输给其它应用程序或保存到固定存储(以IO流的方式)反序列化把对象序列化的字节数据转换为JVM里的对象 类或其继承的父类只要实现java.io.Serializable接口,其对象即可被序列化。此接口为标记接口,不包含任何方法。如果没有实现此接口,在序列化时会触发NotSerializable...
2013-08-19 13:53:57
369
原创 11.74 谨慎的使用序列化
化的字节数据转换为JVM里的对象 类或其继承的父类只要实现java.io.Serializable接口,其对象即可被序列化。此接口为标记接口,不包含任何方法。如果没有实现此接口,在序列化时会触发NotSerializableException 使用ObjectInput、ObjectOutput可以序列化对象,典型代码如下,需要注意的是输入/输出方法要互相对应: //序列化对象 private void writeObject(String filePath,Object o
2013-08-19 13:53:57
130
原创 9.65 不要忽略异常
忽略异常指捕获异常对象后不进行任何处理,如下:try{}catch(SomeException e){ //未进行任何处理,异常被忽略 never do this} 以上代码可能导致程序难以调试。在后续的运行中,程序可能在任何一个地方失败等问题。 如果确定此异常是可以被忽略的,那么至少应使用注释进行说明。建议输出一条日志信息...
2013-08-19 13:53:40
119
原创 9.64 尽力保证异常失败的原子性
异常失败的原子性指如果调用对象的方法抛出了异常,那么此对象的状态应与抛出异常前相同。即对象状态不因为抛出异常而改变,只有这样,调用者才可能在捕获异常后进行恢复。 保证异常失败的原子性可能的方式包括:1.执行运算前(这里指执行能够修改对象状态的运算)先检查条件,如检查输入参数值,对象属性。如果不满足条件则触发异常。 2.如果不能检查运算条件,那么应该执行可能触发异常的运算,再...
2013-08-19 13:53:32
199
原创 9.64 尽力保证异常失败的原子性
才可能在捕获异常后进行恢复。 保证异常失败的原子性可能的方式包括:1.执行运算前(这里指执行能够修改对象状态的运算)先检查条件,如检查输入参数值,对象属性。如果不满足条件则触发异常。 2.如果不能检查运算条件,那么应该执行可能触发异常的运算,再执行需要修改对象状态的运算 3.在异常触发后执行修复代码,适用于基于硬盘的数据操作,如文件和数据库 4.复制对象并对其进行运算,如果触发异常不会影响原对象。适用于复制对象不会明显降低性能或增加内存占用的情况(一般来说复制对象可以提高
2013-08-19 13:53:32
74
原创 9.63 在异常详情里包含失败信息
异常类构造函数Throwable(String message)可以设置异常详细信息,详细信息里应包含所有引起此异常的方法,参数,属性等的说明。 自定义异常类可以定义引起异常的参数值替代直接设置String类型的异常信息,此方式使异常类更方便使用,如下:public IllegalPeriodException(int start, int end){ //使用输入参数值拼...
2013-08-19 13:53:13
148
原创 9.62 注释方法抛出的所有异常
基本原则:1.使用@throws注释方法抛出的所有checked exception 2.使用throws声明方法可能抛出的所有checked exception 3.尽可能的使用@throws注释方法抛出的所有unchecked exception 4.不要使用throws声明方法可能抛出的unchecked exception 5.不要使用Excepti...
2013-08-18 20:15:08
970
原创 9.61 合理的处理底层异常
处理底层API抛出的异常包括3种方法:1.上层API先检查输入参数,然后调用下层API以避免触发异常 2.上层API捕获下层API触发的异常后,使用日志进行记录。上层API不触发任何异常 3.上层API捕获下层API触发的异常后,封装为上层API的异常类对象抛出。此方式又称为异常传递链,如下:try{//....}catch(LowerLevelExceptio...
2013-08-18 20:14:44
335
原创 9.60 优先重用标准异常类
常用异常类包括:IllegalArgumentException输入参数值不合法IllegalStateException对象状态不适合调用当前方法,比如调用某个业务方法时对象还未正常初始化,此时应抛出此异常NullPointerException空指针异常IndexOutOfBoundException索引值超出范围Concurrent...
2013-08-18 20:14:25
82
原创 9.60 优先重用标准异常类
初始化,此时应抛出此异常NullPointerException空指针异常IndexOutOfBoundException索引值超出范围ConcurrentModificationException对象被设计为只能使用单线程或线程同步进行修改,但是观察到有多个线程对其进行并发修改,此时应抛出此异常UnsupportedOperationException对象实现了某个接口,但是并没有实现此接口的所有方法,调用这些未实现的方法应抛出此异常。比如某个只读list类
2013-08-18 20:14:25
67
原创 9.59 避免滥用checked exception
checked exception要求调用者必须使用try/catch进行捕获,否则编译时会提示错误。假如异常是不可恢复的,或者调用者捕获后只能进行如下处理,那么不要使用checked exception:try{//...}catch(TheCheckedException e){ throw new AssertionError();//无意义的处理}try{//...
2013-08-18 20:13:59
71
原创 9.58 正确的使用异常
Java的异常包括checked exception和unchecked exception,后者又包括runtime exception和error。使用基本原则包括:1.如果异常是可恢复的,那么应使用checked exception。调用者必须使用try/catch捕获checked exception并处理(如果捕获那么编译时会提示错误) 2.如果异常是不可恢复的,那么应使...
2013-08-18 20:13:45
75
原创 9.57 仅对异常条件使用异常判断
如下代码错误的使用了异常判断,此种用法难以调试,并且JVM很难对其进行优化: public void sayHello(String[] names){ int i=0; try{ while(true) System.out.println(names[i++]);//never do this }catch(ArrayIndexOutOfBounds...
2013-08-16 14:49:17
68
原创 9.57 仅对异常条件使用异常判断
ut.println(names[i++]);//never do this }catch(ArrayIndexOutOfBoundsException e){ e.printStackTrace(); } } 正确的用法是: public void sayHello(String[] names){ for(String name:names) System.out.println(name); } 对于状态相关的方法,应提供状态测试方法,以
2013-08-16 14:49:17
54
原创 8.56 遵守一般命名约定
字面上的命名约定:包1.使用域名反写2.每部分不要超过8个字符3.不要使用java,javax开头com.bingo.hello类型(类,接口,Annotation)1.首字母大写2.尽量不要使用缩写HttpUrl(建议不要使用HTTPURL)方法和属性1.首字母小写2.尽量不要使用缩写3.JavaBean必须...
2013-08-16 14:49:08
72
原创 8.56 遵守一般命名约定
大写2.尽量不要使用缩写HttpUrl(建议不要使用HTTPURL)方法和属性1.首字母小写2.尽量不要使用缩写3.JavaBean必须使用getter/setter 常量全部大写MIN_VALUE局部变量首字母小写 泛型参数全部大写,尽量不超过2个字符T,E,K,V,T1,T2 语法上的命名没有比较通用的约定,以下仅仅是建议:1.接口可使用able,ible结尾,如Runnable 2
2013-08-16 14:49:08
45
原创 8.55 谨慎的进行性能优化
基本原则包括:1.努力写出好的程序而不是快的程序,不要为了性能而牺牲程序架构原则。好的程序应尽可能的遵守高内聚,低耦合(information hiding)原则。如果程序模块/层次分明,那么后期可以较轻松的进行性能优化 2.努力避免做出影响性能的设计决定。需要考虑的方面包括:与外部系统的交互,系统内部模块之间的交互,通讯协议,数据格式,API。 3.考虑API设计对性能优...
2013-08-16 14:48:59
53
原创 8.54 谨慎的使用本地方法
本地(native)方法可调用JVM所在的操作系统提供的方法(也可以是自行用C、C++等写的方法),使用本地方法缺点包括:1.本地方法需要自行管理内存,如果管理不当可能导致整个应用崩溃,因此本地方法是不安全的2.本地方法依赖操作系统,因此不是跨平台的3.难以调试,调用本地方法较耗时(这里的调用不是指本地方法的执行时间) 建议尽可能少的使用本地方法,在部署前应进行详尽测试。不...
2013-08-16 14:48:42
124
原创 8.53 在反射里使用接口
使用反射(reflection)创建对象,访问方法和属性的缺点包括:1.不能在编译时进行类型检查2.反射代码比较繁复3.性能较低,可能比正常的方法调用低2-50倍 如果被反射的类继承了父类或实现了接口,那么可使用接口/父类类型引用此反射类,然后调用相关方法,以下代码通过反射调用ArrayList对象的add(): @Test public void doByRefl...
2013-08-16 14:48:29
172
原创 8.52 通过接口类型引用对象
通过接口类型引用对象将使得代码具有更高的灵活性,如下通过接口List引用Vector对象:List<String> list=new Vector<String>(); 基本原则包括:如果对象具有合适的接口类型/父类,那么应使用此接口类型/父类引用对象 ...
2013-08-15 08:52:28
69
原创 8.50-8.51 避免使用String代替更合适的数据类型和注意String拼接性能
如果有更合适的数据类型,应使用此类型,而不要使用String,基本原则包括:1.String不适合代替int,float,boolean等性能更高的数据类型 2.String不适合替代枚举类型 3.String不适合替代集合类型,如应返回Address类的对象,替代返回类似“中国:广东”这样的字符串来表示地址 4.String不适合替代功能实现(capability...
2013-08-15 08:52:14
124
原创 8.50-8.51 避免使用String代替更合适的数据类型和注意String拼接性能
合替代枚举类型 3.String不适合替代集合类型,如应返回Address类的对象,替代返回类似“中国:广东”这样的字符串来表示地址 4.String不适合替代功能实现(capability),如要求key值对每个调用者是唯一的,并且只能由调用者访问,此情况就不适合用String作为key值,具体例子可参考原书 String在JVM里实现为不可变对象,因此在拼接字符串时,如果使用String类型,可能会创建多个String对象,导致性能降低。建议使用StringBuilder,Str
2013-08-15 08:52:14
93
原创 8.49 优先使用基本数据类型代替封装对象类型
JDK5后基本数据类型都有一个对应的封装对象类型(boxed primitive),如int对应Integer。两者区别包括:1.基本数据类型仅有数据值,而封装对象类型可能具有相同的数据值但是却是不同的对象,如:int i=42,j=42;System.out.println(i==j);//打印trueInteger a=Integer.valueOf(42);Int...
2013-08-15 08:52:01
254
原创 8.49 优先使用基本数据类型代替封装对象类型
具有相同的数据值但是却是不同的对象,如:int i=42,j=42;System.out.println(i==j);//打印trueInteger a=Integer.valueOf(42);Integer b=Integer.valueOf(42);System.out.println(a==b);//打印false 2.封装对象类型具有一个特殊值null,基本数据类型不具有此值 3.基本数据类型在计算性能和占用内存上,比封装对象类型更好。 基本数据类型和
2013-08-15 08:52:01
92
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人