“不积跬步,无以至千里,不积小流,无以成江海”,程序员如何提高代码质量?我们不仅要知其然,还要知其所以然,我们要从点点滴滴的积累开始的。这篇帖子里记录了编程时的应该注意的一些细节,如有需要后续还会补充,希望通过不断的积累,提高编程质量。
可序列化接口Serializable
类实现Serializable接口的目的是为了可持久化,比如网络传输或本地存储,为系统的分布或异步部署提供先决支持条件。若没有序列化,现在我们熟悉的远程调用,对象数据库都不可能存在。
序列化和反序列化是对应的,以下用代码描述实现了序列化接口Serializable的类在磁盘上的存储过程及反序列化,其在网络上的传输道理也是一样的。
package org.iti.wxl.serializable; import java.io.Serializable; /** * 实现了Serializable的实体类 * */ public class Person implements Serializable{ private static final long serialVersionUID = 6388172609871883630L; private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } }
为模拟序列化的过程我们创建序列化工具类,如下:
package org.iti.wxl.serializable; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; public class SerializableUtils { private static String FILE_NAME="e:/obj.bin"; //序列化数据保存到磁盘 public static void writeObject(Serializable s){ try { ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(FILE_NAME)); oos.writeObject(s); oos.close(); } catch (IOException e) { e.printStackTrace(); } } //反序列化从磁盘读取数据 public static Object readObject(){ Object obj = null; try { ObjectInput input = new ObjectInputStream(new FileInputStream(FILE_NAME)); obj = input.readObject(); input.close(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return obj; } }
序列化保存数据到磁盘上
package org.iti.wxl.serializable; public class Producer { public static void main(String[] args) { Person p = new Person(); p.setName("小明"); // 序列化保存到磁盘上 SerializableUtils.writeObject(p); } }
反序列化,从磁盘读取数据:
package org.iti.wxl.serializable; public class Consumer { public static void main(String[] args) { //反序列化 Person p =(Person)SerializableUtils.readObject(); System.out.println(p.getName()); } }
在反序列化时,若类的版本号serialVersionUID不一致,反序列化时会报一个InvalidClassexception异常,另外在反序列化时,类中的构造函数不会执行。
奇偶校验用偶校验,避免使用奇校验
JDK提供的奇偶校验代码模拟如下:
public class Remainder { //dividend被除数,divisor除数 public static int remainder(int dividend, int divisor) { return dividend - dividend/divisor*divisor; } }
当使用取模运算“%”做奇偶校验时,JDK会依照以上公式进行运算,此时dividend为要校验的数,divisor=2我们发现当被除数为负数且为奇数时,余数为-1,如果我们的奇偶校验公式为i%2 =1 ? "奇数":"偶数";那么当i为负奇数时结果判断会错误,因此我们做奇偶校验时要用偶校验,即:i%2 == 0 ? "偶数":"奇数";
java中的引用问题
java中没有指针的概念,但我们要理解另一个名词“引用”。看下面的例子:
实体类
public class IntString { private Integer no; private String str; public Integer getNo() { return no; } public void setNo(Integer no) { this.no = no; } public String getStr() { return str; } public void setStr(String str) { this.str = str; } @Override public String toString() { return "IntString [" + (no != null ? "no=" + no + ", " : "") + (str != null ? "str=" + str : "") + "]"; } }
测试类:
public class Test { public static void main(String[] args) { List<IntString> test = new ArrayList<IntString>(); IntString is1 = new IntString(); is1.setNo(1); is1.setStr("一"); IntString is2 = new IntString(); is2.setNo(2); is2.setStr("二"); IntString is3 = new IntString(); is3.setNo(3); is3.setStr("三"); test.add(is1); test.add(is2); test.add(is3); List<IntString> newtest = new ArrayList<IntString>(); newtest = test; // List<IntString> newtest = test; System.out.println("前" + newtest); test.get(0).setStr("1"); System.out.println("后" + newtest); } }
输出结果:
前[IntString [no=1, str=一], IntString [no=2, str=二], IntString [no=3, str=三]] 后[IntString [no=1, str=1], IntString [no=2, str=二], IntString [no=3, str=三]]
程序中改变了test实体里的一个对象的某个参数的值,但是打印出newTest后发现它的内部对象值发生了变化,解释如下:newtest = test时,newTest和test两个名字虽然不一样,但是都指向同一块内存地址,test发生变化也就是newTest发生了变化。
java中基本类型可以分为三类,字符类型char,布尔类型boolean以及数值类型byte、short、int、long、float、double,对于非基本类型的对象类数据都是采用引用的方式来处理,那么在做赋值操作“=”时,是引用的赋值,两个不用名称的应用指向同一个地址,其中一个数值发生变化两个就都发生变化了。
另外,对于基本类型,JVM提供常量池,用到某数值的时从常量池里取值,这个时候用==判断是否相等,数值相等时一定相等,“==”判断的是地址相等。而对于非基本类型数值相等也不一定“==”,因此我们应该用equals方法来判断值相等,而对于在内存中只存在一份的判断可以用“==”例如字节码等。
相关推荐
### 编程修养——养成良好编程习惯提高个人编程能力 #### 什么是好的程序员? 成为一位优秀的程序员,并非单纯取决于掌握了多少技术细节或是编程速度有多快。实际上,优秀的程序员应该具备多方面的能力和素质: 1...
这是一份综合性的学习资料,旨在帮助开发者养成良好的编程习惯,从而提高整体的编程素养。 首先,我们来看"代码大全讲义.ppt"。这份讲义可能是对《代码大全》这本书的全面总结或深入解读。《代码大全》是一部经典的...
在C++编程中,良好的编码风格对于初学者来说至关重要,因为它不仅影响代码的可读性和维护性,还能帮助程序员形成规范的编程习惯。以下是一些关键的编程风格指南: 1. 防止重复编译:在头文件中使用`#ifndef`、`#...
编程习惯是每位程序员都应该重视并...综上所述,遵循良好的编程习惯,特别是关于头文件和定义文件的组织,能够大大提高代码质量,降低维护成本,从而提高整体项目效率。养成这些习惯将对程序员的事业产生积极的影响。
总的来说,养成良好的编程习惯,尤其是注重注释的使用和格式,可以显著提高代码的可读性,降低维护成本,提升软件质量。对于初学者,这有助于更快地理解代码逻辑;对于教师和培训者,可以提高教学效果;对于项目管理...
**C++编程规范——养成良好编程习惯** 编程规范在软件开发中扮演着至关重要的角色,尤其是在C++这种复杂的编程语言中。它不仅有助于提高代码的可读性,还能减少潜在的错误,使得团队协作更加高效。遵循统一的编程...
### 编程修养——良好编程习惯的养成 在IT行业中,一名优秀的程序员不仅仅是掌握大量技术细节或具备快速编码能力的人。事实上,一个优秀的程序员应当具备一系列综合性的素养,这些素养涵盖了个人品质、团队协作能力...
在软件开发过程中,良好的编程习惯对于提高程序的质量、维护性和可读性至关重要。对于C++这样的强类型语言来说,养成良好的编程习惯尤为重要。本文主要探讨C++程序中的注释写作技巧,以提升代码的可读性和可维护性。...
【C语言编程习惯】是提升编程能力的关键,它关乎到程序员的素养和代码质量。成为一名C语言高手并不只是掌握技术细节或快速编程,更重要的是具备深入研究、创新思维、团队合作、谦逊谨慎以及编写高质量代码的能力。...
通过上述内容可以看出,良好的C++编程习惯对于提升代码质量和效率具有重要意义。特别是针对内存管理这一难点,利用C++类进行封装可以极大地简化内存管理过程。此外,不断积累、提炼与求精的工作习惯同样非常重要,它...
综上所述,这本书的重点在于提醒程序员注意软件质量,避免陷入编程误区,提倡良好的编程习惯,包括编写清晰的注释、合理的文档、严谨的设计以及关注性能优化等方面。通过学习这些原则和方法,程序员能够提高代码质量...
通过培养良好的编程习惯,不仅能显著提升代码质量,还能增强个人的职业形象和团队协作效率。每个程序员都应该将其视为职业生涯中不可或缺的一部分,不断学习和实践,从而成为真正的“程序匠”,创造出既实用又优雅的...
【编程习惯】编程习惯是程序员的基本素养之一,它关乎到代码的质量、可读性、可维护性和团队协作效率。...养成良好的编程习惯,不仅能够提升个人编程能力,还能在团队合作中减少误解,提高开发效率。
有些程序员由于平时没有养成良好的编程习惯,在面试时写出的代码质量不高,最终遗憾地与心仪的公司和职位失之交臂。因此,如何在面试时能写出高质量的代码,是很多程序员关心的问题。 代码的规范性 代码的规范性是...
这有助于尽早发现问题,减少回归测试的工作量,并提高代码质量。 通过遵循这些编程习惯,软件开发者可以编写出更健壮、更易于理解和维护的代码,从而提高整个项目的成功率。同时,良好的编程习惯也有助于个人技能的...
编程是一项需要精细思考和严谨态度的工作,良好的编程习惯能够极大地提高代码质量和开发效率。以下是15个编程好习惯的详细解读: 1. **先设计后编码**:在编写代码前,进行初步的设计工作,理解问题本质,规划解决...
通过分析常见的编程错误和解决方法,我们可以总结出两大关键点:养成好的编程习惯和针对自己的工作提高自己的知识含量。 一、好的编程习惯 1. 写程序前打个草稿,可以在心里,最好在纸上,目的要从整体上考虑程序...