java安全编码指南之:方法编写指南
文章目录
- 简介
- 不要在构造函数中调用可以被重写的方法
- 不要在clone()方法中调用可重写的方法
- 重写equals()方法
- hashCode和equals
- compareTo方法的实现
简介
java程序的逻辑是由一个个的方法组成的,而在编写方法的过程中,我们也需要遵守一定的安全规则,比如方法的参数进行校验,不要在assert中添加业务逻辑,不要使用废弃或者过期的方法,做安全检查的方法一定要设置为private等。
今天我们再来深入的探讨一下,java方法的编写过程中还有哪些要注意的地方。
不要在构造函数中调用可以被重写的方法
一般来说在构造函数中只能调用static,final或者private的方法。为什么呢?
如果父类在执行构造函数的时候调用了一个可以被重写的方法,那么在该方法中可能会使用到未初始化的数据,从而导致运行时异常或者意外结束。
另外,还可能到方法获取到未初始化完毕的实例,从而导致数据不一致性。
举个例子,我们定义了一个Person的父类:
public class Person {public void printValue(){System.out.println("this is person!");}public Person(){printValue();}
}
然后定义了一个Boy的子类,但是在Boy子类中,重新了父类的printValue方法。
public class Boy extends Person{public void printValue(){System.out.println("this is Boy!");}public Boy(){super();}public static void main(String[] args) {Person persion= new Person();Boy boy= new Boy();}
}
输出结果:
this is person!
this is Boy!
可以看到Boy调用了自己重写过的printValue方法。
注意,这里并不是说会产生语法错误,而是这样会导致业务逻辑看起来非常混乱。
怎么解决呢?简单办法就是将Person中的printValue置位final即可。
不要在clone()方法中调用可重写的方法
同样的,我们在定义clone方法的时候也不要调用可重写的方法,否则也会产生意想不到的变化。
还是上面的例子,这次我们添加了clone方法到Person类:
public Object clone() throws CloneNotSupportedException {Person person= (Person)super.clone();person.printValue();return person;}
接下来我们添加clone方法到Boy类:
public Object clone() throws CloneNotSupportedException {Boy clone = (Boy) super.clone();clone.printValue();return clone;}
因为在clone方法中调用了可重写的方法,从而让系统逻辑变得混乱。不推荐这样使用。
重写equals()方法
考虑一下父类和子类的情况,如果在父类中我们定义了一个equals方法,这个方法是根据父类中的字段来进行比较判断,最终决定两个对象是否相等。
如果子类添加了一些新的字段,如果不重写equals方法,而是使用父类的equals方法,那么就会遗漏子类中新添加的字段,最终导致equals返回意想不到的结果。
所以一般来说,子类需要重写equals方法。
如果重新equals方法,需要满足下面几个特性:
- reflexive反射性
对于一个Object a来说,a.equals(a)必须成立。
- symmetric对称性
对于一个Object a和Object b来说,如果a.equals(b)==true,那么b.equals(a)==true一定成立。
- transitive传递性
对于Object a,b,c来说,如果a.equals(b)==true,b.equals©==true,那么a.equals©==true一定成立。
- consistent一致性
对于Object a,b来说,如果a和b没有发生任何变化,那么a.equals(b)的结果也不能变。
- 对于非空的引用a,a.equals(null) 一定要等于false
具体代码的例子,这里就不写了,大家可以自行练习一下。
hashCode和equals
hashCode是Object中定义的一个native方法:
@HotSpotIntrinsicCandidatepublic native int hashCode();
根据Oracle的建议,如果两个对象的equals方法返回的结果是true,那么这两个对象的hashCode一定要返回同样的int值。
为什么呢?
我们看下下面的一个例子:
public class Girl {private final int age;public Girl(int age) {this.age = age;}@Overridepublic boolean equals(Object o) {if (o == this) {return true;}if (!(o instanceof Girl)) {return false;}Girl cc = (Girl)o;return cc.age == age;}public static void main(String[] args) {HashMap<Girl,Integer> hashMap= new HashMap<>();hashMap.put(new Girl(20), 20);System.out.println(hashMap.get(new Girl(20)));}
}
上面的Girl中,我们定义了equals方法,但是并没有重写hashCode,最后返回的结果是null。
因为我们new了两次Girl这个对象,最后导致native方法中两个不同对象的hashCode是不一样的。
我们可以给Girl类中添加一个hashCode方法:
public int hashCode() {return age;}
这样就可以返回正确的值。
compareTo方法的实现
我们在实现可比较类的时候,通常需要实现Comparable接口。Comparable接口定义了一个compareTo方法,用来进行两个对象的比较。
我们在实现compareTo方法的时候,要注意保证比较的通用规则,也就是说,如果x.compareTo(y) > 0 && y.compareTo(z) > 0 那么表示 x.compareTo(z) > 0.
所以,我们不能使用compareTo来实现特殊的逻辑。
最近看了一个日本的电影,叫做dubo默示录,里面有一集就是石头,剪刀,布来判断输赢。
当然,石头,剪刀,布不满足我们的通用compareTo方法,所以不能将逻辑定义在compareTo方法中。
本文的代码:
learn-java-base-9-to-20/tree/master/security
本文已收录于 http://www.flydean.com/java-security-code-line-method/
最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!
欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!
java安全编码指南之:方法编写指南相关推荐
- java clone方法_java安全编码指南之:方法编写指南
简介 java程序的逻辑是由一个个的方法组成的,而在编写方法的过程中,我们也需要遵守一定的安全规则,比如方法的参数进行校验,不要在assert中添加业务逻辑,不要使用废弃或者过期的方法,做安全检查的方 ...
- java多线程编码实现_Java多线程编码
Java多线程编码 多线程一直是编写程序代码的一个核心,Java中实现方法有以下两种: 一.继承自Thread class Mythread extends Thread [ //方法 public ...
- java安全编码指南之:Thread API调用规则
文章目录 简介 start一个Thread 不要使用ThreadGroup 不要使用stop()方法 wait 和 await 需要放在循环中调用 简介 java中多线程的开发中少不了使用Thread ...
- java jsp学习指南_JSP教程–最终指南
java jsp学习指南 编者注: JavaServer Pages(JSP)技术使您可以轻松创建同时包含静态和动态组件的Web内容. JSP技术提供了Java Servlet技术的所有动态功能,但提 ...
- android技术文档怎么写,技术文档编写指南
技术文档编写指南 首先请阅读文案风格指南 ##学习产品使用方式 最重要的必备的条件就是: 一定要亲自使用这个产品,至少是一遍通顺的流程要走完,不要求每一个接口都一定使用过,但是一个完整的功能片段是使用 ...
- 30条HTML代码编写指南 for入门者
本文总结了30条html代码编写指南,只要在编写HTML代码的过程中牢记它们,灵活运用,你一定会写出一手漂亮的代码,早日迈入专业开发者的行列. 1. 一定要闭合HTML标签 在以往的页面源代码里,经常 ...
- outlook html阅读,Html Email 邮件html页编写指南
前言 写过邮件的html的童学应该都知道,邮件的html一般都用table来布局,为什么呢?原因是大多数的邮件客户端(比如Outlook和Gmail),会过滤HTML设置,让邮件面目全非. 经过多次的 ...
- [转] Bookmarklet(书签工具)编写指南
为什么80%的码农都做不了架构师?>>> 作者: 阮一峰 日期: 2011年6月11日 前一段日子,我写了两个Bookmarklet----"短网址生成"和 ...
- 基于Asterisk的VoIP开发指南(2)——Asterisk AGI程序编写指南
5. Asterisk AGI程序编写指南 5.1概述 很多时候,我们需要在拨号方案中做某些业务逻辑的判断或者外部数据库的查询,根据具体地需要,有几种做法: 1.使用Asterisk的通道变量. ...
最新文章
- python投资组合
- Python元组与字典详解
- 线程池的几个重要参数?—— 七大参数
- Geoserver中切割离线瓦片TileLayer预览时放大之后缺失
- springmvc异常处理器
- mysql执行SQL脚本
- matlab plotyy 坐标轴设置,[转载]Matlab plotyy画双纵坐标图实例
- 侧脸生成正脸概论与精析
- golang中channal容量的问题
- win10删除提示找不到该项目
- 学习C语言需要学oracle,什么是C语言? 为什么要学习C语言?
- 刚开发的游戏《天黑请闭眼》
- 根号二用计算机怎么算,Sqrt-如何计算根号2
- 【数据科学家】什么是数据科学?
- python发邮件详解,smtplib和email模块详解
- ESP8266的STA模式AP模式配置
- 5.8 前端开发日报
- Android手游外挂入侵----寓攻于守,方能破敌
- SQLDER--工具参数--中英文对照
- 机器人企业如何在激流勇进的市场中,深耕落地,突出重围?