Java构造器调用含if校验的setter方法时对象初始化失败问题咨询
问题产生原因
- 核心错误为字符串比较逻辑误用了
==/!=运算符:Java中该运算符用于对象对比时,判断的是两个对象是否指向同一块内存地址,而非对比内容是否相等。 substring()方法返回的是新创建的堆内字符串对象,和代码中写死的.com/.nz字符串常量存储在不同内存区域,地址永远不同,因此原有后缀判断条件永远为真,只要邮箱长度满足截取要求就会触发异常抛出。- 原有逻辑存在隐含漏洞:如果传入的邮箱长度小于3,调用
substring()会直接抛出字符串索引越界异常,校验逻辑未覆盖该场景。
修复方案
将字符串对比改为使用equals()方法,同时补充前置长度校验,避免索引越界:
public void setEmail(String email) throws Exception { // 前置判空、校验最小长度、校验@符号存在 if (email == null || email.length() < 3 || email.indexOf('@') == -1) { throw new Exception("[ERROR] Email not correct"); } String suffix4 = email.substring(email.length() - 4); String suffix3 = email.substring(email.length() - 3); // 用常量调用equals避免空指针 if (!".com".equals(suffix4) && !".nz".equals(suffix3)) { throw new Exception("[ERROR] Email not correct"); } this.email = email; }
额外优化建议
不要在构造方法中调用可被重写的setEmail方法,避免子类重写该方法后父类初始化时出现不可预期的行为,可以把校验逻辑抽成私有静态方法,构造器和setEmail共同调用该私有方法完成校验。
内容的提问来源于stack exchange,提问作者Sapehi
相关产品推荐
相关产品推荐

