- 浏览: 127858 次
- 性别:
- 来自: 北京
最新评论
-
C_J:
有必要这么鸡冻咩?
编写自己的ClassLoader知识点 -
jason61719:
你这不是说了等于没说吗……就解析个loadClass(),谁不 ...
编写自己的ClassLoader知识点 -
jiming:
tedeyang 写道很好的改进,不过话说回来,mybatis ...
开源,从关注产品社区做起(ibatis3.x的最近一个issue展示) -
C_J:
独爱Java 写道好像实际用处并不是很大,只是多了解了有这个东 ...
Java内存模型笔记 -
独爱Java:
好像实际用处并不是很大,只是多了解了有这个东西而已。。。
Java内存模型笔记
可变hashcode的隐患
为识别对象,JDK为每个Object类都定义了一个hashcode,Object的类的hashcode是根据对象的内存地址做hash算法得出来的,String类则自己重写了hashcode()方法,是根据字符串的每个字符做算法累加起来的,Integer在直接返回value的值。
而很多时候,对于应用系统的一些类(Java Bean),是要根据属性来计算hashcode而非内存地址,就像String类。所以会去覆盖Object的equals方法。其实重写就重写了,但是出于技术上的要求,JDK的一些数据结构Collection作为一个数据的容器,它需要唯一定位某个对象,而判定对象是否相等的标准是:1,hashcode是否相等;2,equals函数是否返回true。所以如果这些Java Bean用到这些Collection的话重写equals就必须同时重写hashcode了。
但这不是重点,重点是另外一个问题:可变的hashcode带来的BUG。
大师Ted给出了例子,如下:
import java.util.*; public class Person implements Iterable<Person> { public Person(String fn, String ln, int a, Person... kids) { this.firstName = fn; this.lastName = ln; this.age = a; for (Person kid : kids) children.add(kid); } // ... public void setFirstName(String value) { this.firstName = value; } public void setLastName(String value) { this.lastName = value; } public void setAge(int value) { this.age = value; } public int hashCode() { return firstName.hashCode() & lastName.hashCode() & age; } // ... private String firstName; private String lastName; private int age; private List<Person> children = new ArrayList<Person>(); } // MissingHash.java import java.util.*; public class MissingHash { public static void main(String[] args) { Person p1 = new Person("Ted", "Neward", 39); Person p2 = new Person("Charlotte", "Neward", 38); System.out.println(p1.hashCode()); Map<Person, Person> map = new HashMap<Person, Person>(); map.put(p1, p2); p1.setLastName("Finkelstein"); System.out.println(p1.hashCode()); System.out.println(map.get(p1)); } }
可以看到这个Person重写了hashcode,是属性的hashcode做与运算得出的结果。但是注意到,当p1对象作为key放入HashMap后,随后改变了lastName的属性,导致p1对象的hashcode发生了改变,从而System.out.println(map.get(p1));直接输出null。
所以可以看到,在重写hashcode的时候要特别注意可变的hashcode的影响,为了消除这种隐患,最好给属性加上final的限制。
序列化安全问题
java中序列化对象可以用户磁盘存储和网络传输对象等,但如果不经过任何处理则这些流都是明文的,具有安全隐患,我们通过模糊化处理或使用SealedObject加密等方法来保证安全,如下:
1,模糊化处理,如下:
JAVA对于序列化、反序列化的类是利用ObjectOutputStream、ObjectIntputStream实现,如果需要序列化的类没有writeObject和readObject的方法话,则会调用默认的序列化方式,所以只要重写这两个方法就可以实现自定义的方式来增加安全性等特殊处理(JDK应该是考虑到了安全等问题才给与扩展),如下:
package com.tedneward; public class Person implements java.io.Serializable { public Person(String fn, String ln, int a) { this.firstName = fn; this.lastName = ln; this.age = a; } public String getFirstName() { return firstName; } public String getLastName() { return lastName; } public int getAge() { return age; } public Person getSpouse() { return spouse; } public void setFirstName(String value) { firstName = value; } public void setLastName(String value) { lastName = value; } public void setAge(int value) { age = value; } public void setSpouse(Person value) { spouse = value; } private void writeObject(java.io.ObjectOutputStream stream) throws java.io.IOException { // "Encrypt"/obscure the sensitive data age = age << 2; stream.defaultWriteObject(); } private void readObject(java.io.ObjectInputStream stream) throws java.io.IOException, ClassNotFoundException { stream.defaultReadObject(); // "Decrypt"/de-obscure the sensitive data age = age >> 2; } private String firstName; private String lastName; private int age; private Person spouse; }
2,使用SealedObject对对象进行加密,然后序列化,如下:
import java.io.Serializable; import java.security.Security; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SealedObject; import javax.crypto.SecretKey; public class MainClass { public static void main(String args[]) throws Exception { Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); SecretKey secretKey; Cipher encrypter, decrypter; secretKey = KeyGenerator.getInstance("DES").generateKey();// des加密 encrypter = Cipher.getInstance("DES"); encrypter.init(Cipher.ENCRYPT_MODE, secretKey); decrypter = Cipher.getInstance("DES"); decrypter.init(Cipher.DECRYPT_MODE, secretKey); MyClass cust, unsealed; SealedObject sealed; cust = new MyClass(); cust.name = "Paul"; cust.password = "password"; // Seal it, storing it in a SealedObject sealed = (new SealedObject(cust, encrypter)); FileOutputStream fos = new FileOutputStream(args[0]); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(sealed); oos.close(); // Try unsealing it String algorithmName = sealed.getAlgorithm(); System.out.println(algorithmName); unsealed = (MyClass) sealed.getObject(decrypter); System.out.println("NAME: " + unsealed.name); System.out.println("PASSWORD: " + unsealed.password); } } class MyClass implements Serializable { public String name; public String password; }
发表评论
-
iOS入门(ongoing)
2012-09-13 11:32 1301Record it: The overview of ... -
Stuff about Android
2011-07-09 16:15 1065Foreword: long time ... -
JQuery初体验(Demo)
2011-05-22 13:43 1458Demo:Show <meta content ... -
Java内存模型笔记
2011-04-13 15:48 1538题记: 看到C/C++ ... -
Radiant_The Popular Ruby's CMS Demo篇
2011-04-02 14:49 1241题记: 上篇 记录我第一次安装Rodiant经过和 ... -
Radiant_The Popular Ruby’s CMS安装篇
2011-03-28 00:48 1278题记: 今天第一次参加JE的线下活动,robbin等 ... -
关于Azul 并发垃圾回收器
2011-03-26 14:40 1317题记: 总感觉JE讨论的帖子的东西都比较滞后,所以会 ... -
phpCMS & jQuery是我该做的(阉割了)
2011-02-27 23:02 81WD讲究以plugin挂载为结构,我需要构造一个p ... -
我的玩意:J2ME的Criteria初探
2011-01-20 21:59 1019题记: 前几天跟初中同学聊天,他问我能不能做一个GP ... -
编写自己的ClassLoader知识点
2011-01-13 14:41 1871题记: 看到InfoQ关于ClassLoader的文 ... -
周末好玩,用短信控制你的计算机
2011-01-10 16:34 2986Snapshot: 详情 ... -
About Dock Plugin on Mac
2010-11-21 22:47 1462题记: 第一次接触MAC的开发..... ... -
体验OSGi(helloworld.jar)—富app的热拔插
2010-10-18 23:22 2436记得以前工作的时候,有天direct manager问 ... -
MongoDB on DAO with Java Language
2010-08-26 19:17 1425A Quick Tour Using the Java d ... -
Getting Start on Mongodb
2010-08-26 01:29 1504题记: 最近老和同学聊到non-relational ... -
Java Media Framework本地玩转摄像头
2010-08-04 00:57 17331、简介The JavaTM Media Framework ... -
从WeakLogHandler应用看Java的引用、引用队列
2010-06-14 00:58 1499题记: 前几天讨论到WeakHashMap(这个是个弱引用的 ... -
《重构》读书笔记
2010-05-09 00:05 1045Martin Fowler于2003年出版 ... -
RPC之WebServices&RMI&JMS,phprpc框架?(待续)
2010-05-06 22:31 55前段时间写过基本的WebServices,也没再做深入 ... -
Java应用中的SQL注入攻击和防范
2010-04-24 01:06 6712说说自己对注入的 ...
相关推荐
在Java编程语言中,序列化(Serialization)和重写`hashCode`及`equals`方法是两个重要的概念,它们各自有着特定的用途,并且在某些情况下相互关联。下面将详细阐述这两个概念及其应用。 首先,Java序列化是将一个...
### Java 高级特性详解 #### 一、`hashCode` ...正确地重写 `equals` 和 `hashCode` 方法、使用 `Comparator` 进行排序、利用反射机制和序列化技术,以及实现 `clone` 方法都是开发高质量 Java 应用程序的重要技能。
equals()和hashcode()这两个方法都是从object类中继承过来的。当String 、Math、还有Integer、Double。。。。等这些封装类在使用equals()方法时,已经覆盖了object类的equals()方法.
Java反序列化漏洞是一种安全问题,主要出现在Java应用程序中,当程序不安全地处理来自不可信源的反序列化数据时,攻击者可以构造恶意序列化对象,导致非预期的对象创建或代码执行。本文将深入探讨Java反序列化的基本...
总的来说,URLDNS反序列化链是Java安全领域的一个重要知识点,了解其工作原理和防范措施对于开发安全的应用至关重要。通过学习和理解这种攻击手段,开发者可以更好地保护他们的系统免受潜在的威胁。
hashCode 是一种用于查找和排序的机制,在数据结构中 plays a crucial role。下面我们将对 hashCode 的用法进行详细的解释。 hashCode 的作用 hashCode 的主要作用是用于查找和排序。在查找和排序的过程中,我们...
hashCode() 和 equals() 的本质区别和联系 Java 中的每个对象都有 hashCode() 和 equals() 方法,这两个方法的正确实现对于 Java 开发人员来说是非常重要的。本文将详细介绍 hashCode() 和 equals() 的本质区别和...
### 深入理解 HashCode 方法 #### 一、HashCode 的基本概念与...通过合理地设计和实现 `HashCode`,可以大大提高程序的运行效率和性能。对于自定义类来说,正确地重写 `hashCode()` 和 `equals()` 方法是非常必要的。
在Java编程语言中,`equals()` 和 `hashCode()` 方法是Object类中的两个核心方法,所有类都默认继承自Object类。这两个方法在处理对象比较和集合操作时起着至关重要的作用。当我们创建自定义类并需要对对象进行精确...
对于Jackson的集成,只需要添加对应的依赖,Immutables会自动处理不可变对象的序列化和反序列化。同样,对于Gson,也有对应的适配器帮助处理。至于MongoDB,Immutables提供了BSON编码/解码器,使得不可变对象可以...
"Java中equals、hashcode和==的区别" Java 中 equals、hashcode 和==的区别是 Java 编程语言中一个经常遇到的问题。这三个概念都是用来比较对象的,但是它们之间存在着本质的区别。 首先,==号是Java中的一个...
在Java编程语言中,`hashCode()`和`equals()`方法是非常重要的概念,它们不仅对于深入理解Java内存管理至关重要,也是实现自定义类的关键部分之一。本文将详细介绍这两个方法的工作原理、使用场景以及它们之间的关系...
在Java编程语言中,`hashCode()` 和 `equals()` 方法是两个非常重要的概念,尤其是在处理对象比较和哈希表(如 `HashMap` 或 `HashSet`)时。这两个方法来源于 `Object` 类,是所有Java类的基类,因此,每个自定义类...
2. **可变性**:如果两个对象的`hashCode`值相同,并不一定意味着这两个对象相等。 ### 3. 实例分析 假设我们有一个名为`Person`的类,其中包含`name`和`age`两个属性。为了使`Person`对象能够正确地工作在`...
有许多人学了很长时间的Java,但一直不明白hashCode方法的作用以及equals()和==的区别,我来解释一下吧。首先,想要明白hashCode的作用,你必须要先知道Java中的集合。总的来说,Java中的集合(Collection)有两类,...
本文还介绍了定义对象的相等性、实施equals()和hashCode()的需求、编写自己的equals()和hashCode()方法。通过统一定义equals()和hashCode(),可以提升类作为基于散列的集合中的关键字的使用性。
在Java编程语言中,反射(Reflection)是一种强大的...但需要注意的是,滥用反射可能导致安全问题和性能下降,因此在实际使用中需谨慎权衡。同样,正确实现和使用hashcode也是优化程序性能和保证数据结构正确性的关键。
Java的`Objects.equals()`和`Objects.hash()`方法是帮助我们更安全地处理`equals()`和`hashCode()`的实用工具。`Objects.equals(a, b)`可以避免空指针异常,当a或b为null时,它会正确处理。而`Objects.hash()`可以...
equals 方法和 hashCode 方法是 Java 语言中两个重要的方法,它们都是在 Object 类中定义的。equals 方法用于比较两个对象是否相等,而 hashCode 方法用于返回对象的哈希码。 在 Java 的 Object 类中,equals 方法...