为什么不建议使用is开头作为变量名

为什么不建议使用is开头作为变量名



前言

之前有看到过这个面试题,然后写变量相关文章的时候想到了这个问题,所以在这边补充一下,讲一下为什么不建议。


一、为什么不建议?

不建议的原因主要是基于几个编程规范和最佳实践。 主要有三个点:RPC框架的序列化问题JavaBeans规范可读性和一致性

(感觉最主要的就是在序列化与反序列化的过程中,非Boolean类型的变量的名称如果使用is开头,没做特殊处理的情况下,假如变量名为isSuccess的变量在反序列化的过程中,可能会被认定为Boolean类型变量名为success变量,导致取不到值)

1、RPC框架的序列化问题

在RPC(远程过程调用)框架中,变量的命名方式会影响属性的序列化和反序列化过程。如果变量名以“is”开头,RPC框架在反向解析时可能会误将其识别为布尔类型的getter方法,导致属性值获取不到,从而抛出异常。例如,如果一个变量名为“isSuccess”,RPC框架可能会将其解析为“success”而不是“isSuccess”,导致属性值无法正确获取。

2、JavaBeans规范

JavaBeans规范对属性的getter和setter方法命名有明确规定。对于基本数据类型(包括布尔类型),getter方法应该以“get”开头,而对于布尔类型,其getter方法通常可以特殊地以“is”开头。然而,这种以“is”开头的命名方式在某些情况下可能会导致混淆和错误,特别是在与RPC框架或其他序列化机制交互时。

3、可读性和一致性

使用一致的命名规范可以提高代码的可读性和可维护性。如果变量名以“is”开头,可能会与其他不以“is”开头的变量名混淆,导致代码阅读者难以区分哪些是布尔类型的变量,哪些不是。此外,这种不一致的命名方式也可能导致在编码过程中出现错误。

代码示例

1、对比

  1. 不好的做法:
public class User {  
    private boolean isActive;  
    private boolean isAdmin;  
  
    public boolean isIsActive() { // 方法名冗余且不符合JavaBeans规范  
        return isActive;  
    }  
  
    public boolean isIsAdmin() { // 方法名同样冗余且不符合规范  
        return isAdmin;  
    }  
}
  1. 好的做法
public class User {  
    private boolean active; // 直接使用描述性名称  
    private boolean admin;  // 同上  
  
    public boolean isActive() { // 符合JavaBeans规范的getter方法  
        return active;  
    }  
  
    public boolean isAdmin() { // 同样是符合规范的getter方法  
        return admin;  
    }  
}

2、例子

有一个常见的场景会与以is开头的变量名相关,那就是当这些变量名与JavaBean规范中的boolean类型getter方法命名冲突时。JavaBean规范要求boolean类型的getter方法应该以is开头,而不是get。这可能导致在序列化时,如果使用了默认序列化机制(即没有提供自定义的writeObject和readObject方法),序列化框架可能会错误地将这些以is开头的getter方法识别为字段,并尝试序列化它们。

这种情况通常不会直接导致序列化失败,但可能会导致序列化后的数据包含意外的信息,或者在反序列化时无法正确恢复对象状态。

代码示例如下:

import java.io.*;  
  
public class MyObject implements Serializable {  
    private static final long serialVersionUID = 1L;  
  
    private boolean isActive; // 一个普通的boolean字段  
  
    // 正确的getter方法  
    public boolean isActive() {  
        return isActive;  
    }  
  
    public void setActive(boolean active) {  
        isActive = active;  
    }  
  
    // 假设我们还有一个非boolean类型的字段,但它的getter方法命名以is开头  
    private String isExample;  
  
    // 这里getter方法的命名违反了JavaBean规范,可能会导致序列化框架误将其识别为boolean类型的getter  
    public String isExample() {  
        return isExample;  
    }  
  
    public void setExample(String example) {  
        isExample = example;  
    }  
  
    public static void main(String[] args) throws IOException, ClassNotFoundException {  
        MyObject obj = new MyObject();  
        obj.setActive(true);  
        obj.setExample("This is an example"); // 注意这里使用了setExample而不是setIsExample  
  
        // 序列化对象到文件  
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("obj.ser"))) {  
            oos.writeObject(obj);  
        }  
  
        // 尝试反序列化对象  
        MyObject deserializedObj = null;  
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.ser"))) {  
            deserializedObj = (MyObject) ois.readObject();  
        } catch (InvalidClassException e) {  
            // 在这里,我们可能会捕获到InvalidClassException,因为序列化时可能将isExample识别为boolean字段  
            // 反序列化时,当期望一个boolean值而实际上得到一个String时,就会抛出异常  
            e.printStackTrace();  
        }  
  
        if (deserializedObj != null) {  
            System.out.println(deserializedObj.isActive()); // 如果反序列化成功,这里应该输出true  
            System.out.println(deserializedObj.isExample()); // 如果反序列化成功,这里应该输出"This is an example"  
        } else {  
            System.out.println("反序列化失败");  
        }  
    }  
}
  • 12
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Jz_Stu

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

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

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

打赏作者

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

抵扣说明:

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

余额充值