【编写高质量代码:改善Java程序的151个建议】第1章:Java开发中通用的方法和准则___建议1~13

关于学习Java路线总结 掌握这些技术可以让开发者更加高效地进行 Web 开发工作。7. Web 开发:学习 Java 的 Web 开发,包括 Servlet、JSP、MVC 框架等,掌握 HTML、CSS、JavaScript 等前端技术和数据库操作。4. MVC 框架:学习常用的 MVC 框架,如 Struts、Spring MVC 等,了解 MVC 模式的原理和优势,掌握框架的使用方法。6. ORM 框架:学习常用的 ORM 框架,如 Hibernate、MyBatis 等,了解对象关系映射的原理和优势,掌握框架的使用方法。 阅读详情

作为一个由影视圈转行做Java的菜鸟来说,读书是很关键的,本系列是用来记录《编写高质量代码 改善java程序的151个建议》这本书的读书笔记。方便自己查看,也方便大家查阅。

建议1:不要在常量和变量中出现易混淆的字母

建议2:莫让常量蜕变成变量

常量蜕变成变量?你胡扯吧,加了final和static的常量怎么可能会变呢?不可能为此赋值的呀。真的不可能吗?看看如下代码:

import java.util.Random;

public class Demo01 {
    public static void main(String[] args) {
        test02();
    }

    public static void test02() {
        System.out.println("常量会变哦:" + Constant.RAND_CONST);
    }
}

interface Constant {
    public static final int RAND_CONST = new Random().nextInt();
}

RAND_CONST是常量吗?它的值会变吗?绝对会变!这种常量的定义方式是绝对不可取的,常量就是常量,在编译期就必须确定其值,不应该在运行期更改,否则程序的可读性会非常差,甚至连作者自己都不能确定在运行期发生了何种神奇的事情。

   甭想着使用常量会变的这个功能来实现序列号算法、随机种子生成,除非这真的是项目中的唯一方案,否则就放弃吧,常量还是当常量使用。

注意:务必让常量的值在运行期保持不变。

建议3:三元操作符的类型务必一样

建议4:避免带有变长参数的方法重载

建议5:别让null值和空值威胁到变长方法  

client.methodA("china", null);

编译不通过,提示相同:方法模糊不清,编译器不知道调用哪一个方法,但这两处代码反应的味道是不同的。

String str = null;

client.methodA("china", str);

让编译器知道这个null值是String类型的,编译即可顺利通过,也就减少了错误的发生。

建议6:覆写边长方法也循规蹈矩

注意:覆写的方法参数与父类相同,不仅仅是类型、数量,还包括显示形式.

建议7:警惕自增的陷阱

建议8:不要让旧语法困扰你

建议9:少用静态导入

从Java5开始引入静态导入语法(import static),其目的是为了减少字符的输入量,提高代码的可阅读性,以便更好地理解程序。

对静态导入,追寻两个原则:

1、不使用通配符,除非是导入静态常量类;

2、方法名具有明确、清晰表象意义的工具类。

建议10:不要在本类中覆盖静态导入的变量和方法

如果在一个类中的方法及属性与静态导入的方法及属性相同会出现什么问题呢?看下面的代码

import static java.lang.Math.PI;
import static java.lang.Math.abs;

public class Client10 {
    // 常量名于静态导入的PI相同
    public final static String PI = "江疏影";
    //方法名于静态导入的方法相同
    public static int abs(int abs) {
        return 0;
    }

    public static void main(String[] args) {
        System.out.println("PI = "+PI);
        System.out.println("abs(-100) = "+abs(-100));
    }
}

以上代码中定义了一个String类型的常量PI,又定义了一个abs方法,与静态导入的相同。首先说好消息,代码没有报错,接下来是坏消息:我们不知道那个属性和方法别调用了,因为常量名和方法名相同,到底调用了那一个方法呢?运行之后结果为:

e1c0bc2b5c62d542788daaa008182e46dc8.jpg

很明显是本地的方法被调用了,为何不调用Math类中的属性和方法呢?那是因为编译器有一个“最短路径”原则:如果能够在本类中查找到相关的变量、常量、方法,就不会去其它包或父类、接口中查找,以确保本类中的属性、方法优先。

因此,如果要变更一个被静态导入的方法,最好的办法是在原始类中重构,而不是在本类中覆盖。

建议11:养成良好习惯,显示声明UID

序列化Serializable是Java提供的通用数据保存和读取的接口。任何类只要实现了Serializable接口,就可以被保存到文件中,或者作为数据流通过网络发送到别的地方。

package OSChina.Serializable;

import java.io.Serializable;

public class Man implements Serializable {
    private static final long serialVersionUID = 1L;

    private String username;
    private String password;

    public Man(String username, String password) {
        this.username = username;
        this.password = password;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}
package OSChina.Serializable;

import java.io.Serializable;

public class Person implements Serializable {
    private static final long serialVersionUID = 1L;

    private Man man;
    private String username;
    private transient int age;

    public Person() {
        System.out.println("person constru");
    }

    public Person(Man man, String username, int age) {
        this.man = man;
        this.username = username;
        this.age = age;
    }

    public Man getMan() {
        return man;
    }
    public void setMan(Man man) {
        this.man = man;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}
package OSChina.Serializable;

import java.io.*;

public class MainTest {
    private static final String FILE_NAME = "D:/data/rtdata.txt";
    public static void writeSerializableObject() {
        try {
            Man man = new Man("huhx", "123456");
            Person person = new Person(man, "刘力", 21);
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(FILE_NAME));
            objectOutputStream.writeObject("string");
            objectOutputStream.writeObject(person);
            objectOutputStream.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // Serializable:反序列化对象
    public static void readSerializableObject() {
        try {
            ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(FILE_NAME));
            String string = (String) objectInputStream.readObject();
            Person person = (Person) objectInputStream.readObject();
            objectInputStream.close();
            System.out.println(string + ", age: " + person.getAge() + ", man username: " + person.getMan().getUsername());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        writeSerializableObject();
        readSerializableObject();
    }
}

dafda5fb331bb10c25f90ff442a43a1b232.jpg

这是一个简单的JavaBean,实现了Serializable接口,可以在网络上传输,也可以在本地存储然后读取。

序列化和反序列化的类在不一致的情况下,反序列化时会报一个InalidClassException异常,原因是序列化和反序列化所对应的类版本发生了变化,JVM不能把数据流转换为实例对象。刨根问底:JVM是根据什么来判断一个类的版本呢?

通过SerializableUID,也叫做流标识符(Stream Unique Identifier),即类的版本定义的,它可以显示声明也可以隐式声明。显示声明格式如下:

private static final long serialVersionUID = 1867341609628930239L;

serialVersionUID的作用:

JVM在反序列化时,会比较数据流中的serialVersionUID与类的serialVersionUID是否相同,如果相同,则认为类没有改变,可以把数据load为实例相同;如果不相同,抛个异常InviladClassException。

刚开始生产者和消费者持有的Person类一致,都是V1.0,某天生产者的Person类变更了,增加了一个“年龄”属性,升级为V2.0,由于种种原因(比如程序员疏忽,升级时间窗口不同等)消费端的Person类还是V1.0版本,添加的代码为 priavte int age;以及对应的setter和getter方法。

此时虽然生产这和消费者对应的类版本不同,但是显示声明的serialVersionUID相同,序列化也是可以运行的,所带来的业务问题就是消费端不能读取到新增的业务属性(age属性而已)。

通过此例,我们反序列化也实现了版本向上兼容的功能,使用V1.0版本的应用访问了一个V2.0的对象,这无疑提高了代码的健壮性。

显示声明serialVersionUID可以避免对象的不一致,但尽量不要以这种方式向JVM撒谎。

建议12:避免用序列化类在构造函数中为不变量赋值

我们知道带有final标识的属性是不变量,也就是只能赋值一次,不能重复赋值,但是在序列化类中就有点复杂了,比如这个类:

3afd45dea9ce0f41b2b4da91e908f80ce0a.jpg

在构造函数中不允许对final变量重新赋值。

去掉final之后呢?

public class Person implements Serializable {
    private static final long serialVersionUID = 1L;
    public static String perName="程咬金";

    public Person() {
        System.out.println("person constru");
        perName = "秦叔宝";
    }
}
public class Test {
    public static void main(String[] args) {
        System.out.println(perName);
    }
}

f64213fda4d930f6f0356f74660ad987be1.jpg

序列化与反序列化的时候构造函数不会执行。

建议13:避免为final变量复杂赋值

9df249b25333ead77a90d158009590926a8.jpg

现在的Java好像已经命令禁止final的重新赋值了!

Github即将破百万的PDF:编写高质量代码改善JAVA程序的151个建议 在通往"Java技术殿堂"的路上,本书将为你指点迷津!内容全部由Java编码的最佳 实践组成,从语法、程序设计和架构、工具和框架、编码风格和编程思想等五大方面,对 Java程序员遇到的各种棘手的疑难问题给出了经验性的解决方案,为Java程序员如何编写 高质量的Java代码提出了151条极为宝贵的建议。对于每一个问题,不仅以建议的方式从 正反两面蛤出了被实践证明为十分优秀的解决方案和非常精糕的解决方案,而且还分析了 问题产生的根源,犹如醍醐灌顶,让人豁然开朗。 全书-共12章,... 阅读详情

相关推荐

编写高质量代码--改善Java程序的151个建议精要

声明:本文只是把秦小波所著《编写高质量代码--改善Java程序的151个建议》艺术

steveguoshao的专栏 1572

Java学习路线

门永不过时的编程语言——Java 编程开发。 Java编程语言占比: 据官方数据统计,在全球编程语言工程师的数量上,Java编程语言以900万的程序员数量位居首位。 而且很多软件的开发都离不开Java编程,因此其程序员的数量最多。而在以Java编程为核心的开发领域中,javaEE程序员的需求量10年来一直居于首位! Java工程师人才缺口: 根据IDC的统计数字:就2017年来说,我国Java人才...

3446

Java学习路线总结(思维导图篇)

优快云最强Java专栏,包含全部Java基础知识点、Java8新特性、Java集合、Java多线程、Java代码实例,理论结合实战,实现Java的轻松学习。

学Java,找哪吒 19万+

Java学习路线总结,搬砖工逆袭Java架构师

定期分享Java硬核技术干货、分享Java学习路线、分享Java经典面试题

学Java,找哪吒 26万+

R语言实战:非正态数据下的Scheirer–Ray–Hare检验全流程解析

本文详细解析了在R语言中执行Scheirer–Ray–Hare检验的全流程。当数据不满足正态分布假设时,该非参数检验是传统双因素方差分析的有效替代方案。文章从原理、R环境配置、数据准备、代码实现、结果解读到事后比较与可视化,提供了完整的实战指南,帮助研究者稳健地分析多因素实验设计中的主效应和交互效应。

cc789的博客 406

控制障碍函数(Control Barrier Function,CBF) 一、定义

介绍控制障碍函数

Lyajpunov的博客 2万+

2020最新版Java学习路线图--Java语言进阶重点知识

Java学习路线图的第二阶段是Java语言进阶学习,在学习完第一阶段的Java语言入门后,大家对Java语言编程有了初步的认识。 黑马程序员的2020最新版Java学习路线图把Java语言进阶学习分为九个部分:面向对象进阶,常见API,异常,集合,IO,多线程,网络编程,Lambda以及反射。 下面介绍的是Java语言进阶学习阶段的技术要点,跟着学一定会有所收获。如果在被某个知识点卡住了,请不要轻...

CZ-001的博客 8061

DICOM图像知识:深入详解DICOM的层级关系

解析DICOM的四个主要层级:Patient(患者)、Study(检查)、Series(序列)和SOP(服务-对象对),探讨它们之间的关系、各自的唯一标识符以及在实际应用中的用途

编程技术探索者,分享C/C++、C#、Java、数据库等开发经验,聚焦实战技巧与AI兴趣,助力编程爱好者成长。 3305

编写高质量代码:改善Java程序的151个建议(第1章:Java开发中通用的方法和准则___建议1~13)...

作为一个由影视圈转行做Java的菜鸟来说,读书是很关键的,本系列是用来记录《编写高质量代码 改善java程序的151个建议》这本书的读书笔记。方便自己查看,也方便大家查阅。 建议1:不要在常量和变量中出现易混淆的字母 建议2:莫让常量蜕变成变量 建议3:三元操作符的类型务必一样...

chetianyao8457的博客 234

Linux V3H 平台开发系列讲解(摄像头)2.3.1 MAX96912 MAX96717 GMSL1 CSI 2lane配置

​ 单路摄像头,数据流类型YUV422, mipi接口,经过MAX96717 串行器,gmsl1链路 到解串器MAX96712,最后mipi csi 2lane(lane0 lane1)输出到 renesa v3h soc开发板; ​

xian18809311584的博客 580

用 MATLAB 实现鼻子和嘴的检测

为了方便起见,这里我们使用了 CascadeObjectDetector 中自带的 haarcascade_frontalface_alt2.xml 文件,该文件包含了多个包含鼻子和嘴的样本图像。其中 bbox 变量表示检测到的所有鼻子和嘴的边界框信息。在图像处理中,鼻子和嘴的检测是十分重要的一项任务。本文将介绍如何使用 MATLAB 实现鼻子和嘴的检测,并提供相应的源代码。然后,我们可以调用之前创建的 detector 对象来进行鼻子和嘴的检测。综上所述,我们可以使用以上代码实现鼻子和嘴的检测。

qq_39605374的博客 256

改善java程序的151个建议

《编写高质量代码-改善java程序的151个建议》 --秦小波 第一章、开发中通用的方法和准则 1、不要在常量和变量中出现易混淆的字母 long a=0l; --> long a=0L; 2、莫让常量蜕变成变量 static final int t=new Random().nextInt(); 3、三元操作符的类型无比一致 int i=80;...

weixin_30654583的博客 1987

【短距离通信】【WiFi】精讲802.11n/ac/ax mpdu和ampdu最大长度

在 Wi-Fi 标准(802.11n、802.11ac 和 802.11ax)中,和是数据传输的核心概念。理解它们各自的作用以及不同标准下的最大长度限制,有助于深入了解 Wi-Fi 的性能优化机制。以下是对802.11n802.11ac和802.11ax中MPDU和A-MPDU最大长度的详细技术分析和对比。1. MPDU 和 A-MPDU 的基本概念MPDU 是经过 MAC 层处理后的数据单元,主要由MAC层数据帧和物理层的传输头部(PHY headers)组成。

风云说通信 1108

Github即将破百万的PDF:编写高质量代码改善JAVA程序的151个建议(1)

Java程序员遇到的各种棘手的疑难问题给出了经验性的解决方案,为Java程序员如何编写高质量的Java代码提出了151条极为宝贵的建议。对于每一个问题,不仅以建议的方式从正反两面蛤出了被实践证明为十分优秀的解决方案和非常精糕的解决方案,而且还分析了问题产生的根源,犹如醍醐灌顶,让人豁然开朗。全书-共12章,第1~ 3章针对Java语法本身提出了51条建议,例如覆写变长方法时应该注意哪些事项、final 修饰的常量不要在运行期修改、匿名类的构造函数特殊在什么。

2301_79987255的博客 1036

Python爬虫抓取学术期刊数据(Springer、Elsevier)

本文详细介绍了如何使用Python爬虫抓取学术期刊网站(如Springer、Elsevier)上的文章信息,并进行数据清洗和存储。我们使用了requestsSeleniumpandas等技术,通过模拟浏览器行为来绕过反爬虫机制,并将数据保存为Excel文件,方便后续分析。未来,我们可以通过加入更多的期刊网站数据源,扩展爬虫的功能,抓取更多的学术数据。同时,结合自然语言处理(NLP)技术,可以对抓取的文章进行自动化的摘要提取和主题分类,为学术研究提供更多的支持。

2201_76125261的博客 1488

某联达OA任意用户登录漏洞复现

由于`/WebService/Lk6SyncService/DirectToOthers/GetSSOStamp.asm`j接口未作限制,导致可以通过该接口调用`admin`的`cookie`值,通过对`LoginCredence`和`LoginTimestamp`的参数修改,进而实现任意登录进去系统.

千寻的博客 1589

编写高质量代码:改善Java程序的151个建议

本系列是用来记录《编写高质量代码 改善java程序的151个建议》这本书的读书笔记。方便自己查看,也方便大家查阅。 全书共12章,共有151条建议,其中1~3章针对java语法本身提出了51条建议;第4~9章重点针对JDK API的使用提出了80条建议;第10~12章针对程序的性能、开源的工...

chetianyao8457的博客 352

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

转载----编写高质量代码:改善Java程序的151个建议(第1章:JAVA开发中通用的方法和准则___建议1~5)...

阅读目录 建议1:不要在常量和变量中出现易混淆的字母 建议2:莫让常量蜕变成变量    建议3:三元操作符的类型务必一致   建议4:避免带有变长参数的方法重载 建议5:别让null值和空值威胁到变长方法   The reasonable man adapts himself to the world; The unreasona...

dingtuo8134的博客 208

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

编写高质量代码:改善Java程序的151个建议 | 第一章 Java开发中通用的方法和准则

编写高质量代码:改善Java程序的151个建议 | 第一章 Java开发中通用的方法和准则

qq_42605751的博客 450

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

Github即将破百万的PDF:编写高质量代码改善JAVA程序的151个建议

在通往"Java技术殿堂"的路上,本书将为你指点迷津!内容全部由Java编码的最佳实践组成,从语法、程序设计和架构、工具和框架、编码风格和编程思想等五大方面,对Java程序员遇到的各种棘手的疑难问题给出了经验性的解决方案,为Java程序员如何编写高质量的Java代码提出了151条极为宝贵的建议。对于每一个问题,不仅以建议的方式从正反两面蛤出了被实践证明为十分优秀的解决方案和非常精糕的解决方案,而且还分析了问题产生的根源,犹如醍醐灌顶,让人豁然开朗。

老男孩的架构路 247

2024年Java最新Github即将破百万的PDF:编写高质量代码改善JAVA程序的151个建议,2024金九银十

各位读者,由于本篇幅度过长,为了避免影响阅读体验,下面我就大概概括了整理了本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录需要这份系统化的资料的朋友,可以点击这里获取建议104:使用forName动态加载类文件/184各位读者,由于本篇幅度过长,为了避免影响阅读体验,下面我就大概概括了整理了[外链图片转存中…(img-qELoR3Fg-1714907863115)][外链图片转存中…(img-qCnRDxb9-1714907863116)]

2401_84689394的博客 1113

Java编写高质量代码改善程序的151个建议

第一章 Java开发中通用的方法和准则 建议1:不要在常量和变量中出现易混淆的字母; (i、l、1;o、0等)。 建议2:莫让常量蜕变成变量; (代码运行工程中不要改变常量值)。 建议3:三元操作符的类型务必一致; (不一致会导致自动类型转换,类型提升int->float->double等)。 建议4:避免带有变长参数的方法重载; (变长参...

dhmkjv0619的博客 288

怎样才能写出漂亮高质量的java代码?改善JAVA程序的151个建议你看过吗,你想要的答案都在里面了!

怎么写高质量的代码是一个很大的话题,其实面向对象设计的很多原则都能够给我们写代码的时候提供指导,写代码的时候要时刻记得学以致用,而不是敷衍了事,专业的软件工程师必然要能写得一手好代码。

老男孩的架构路 649

改善Java程序的151建议_改善java程序的151个建议

《编写高质量代码-改善java程序的151个建议》--秦小波一、开发中通用的方法和准则1、不要在常量和变量中出现易混淆的字母long a=0l; --> long a=0L;2、莫让常量蜕变成变量static final int t=new Random().nextInt();3、三元操作符的类型无比一致int i=80;String s=String.valueOf(i<100?9...

weixin_39559369的博客 446
上一篇: 死锁、活锁、饿死和阻塞的个人理解
下一篇: 【编写高质量代码:改善Java程序的151个建议】第1章:Java开发中通用的方法和准则___建议14~20
哪 吒
哪 吒 2022年度博客之星TOP 1 2022年度博客之星TOP 1 领域专家: 后端开发技术领域 领域专家: 后端开发技术领域
博客等级 码龄9年 59万+粉丝 2953原创
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哪 吒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值