藏拙首页 | 贴吧 | 藏拙导航 | 藏拙IP搜索
 
查看文章
 



java学习杂谈(三)

2008-07-11 00:24
{1,2,3,4};
System.out.println(A.hashCode());
System.out.println(B.hashCode());

这明明是同一种组合,却是不同的hashCode,加入Set的时候会被当成不同的对象。这个时
候我们就需要自己来重写hashCode()方法了,如何写呢?其实也是基于原始的hashCode(),
毕竟那是操作系统的实现, 找到相通对象唯一的标识,实现方式很多,笔者的实现方式是

首先重写了toString()方法:
return A[0]“ ” A[1]“ ” A[2]“ ” A[3]; //显示上比较直观
然后利用toString()来计算hashCode():
return this.toString().hashCode();
这样上述A和B返回的就都是”1234”,在测试toString().hashCode(),由于String在内存中的副本
是一样的,”1234”.hashCode()返回的一定是相同的结果。

说到这,相信大家能理解得比我更好,今后千万不要再误解hashCode()方法的作用。

3. 关于Class类的成员函数与Java反射机制
很早刚接触Java就听很多老师说过Java的动态运行时机制、反射机制等。确实它们都是
Java的显著特点,运行时加载笔者在第一篇介绍过了,现在想讲讲反射机制。在Java中,
主要是通过java.lang包中的Class类和Method类来实现内存反射机制的。
熟悉C 的人一定知道下面这样在C 中是做不到的: 运行时以字符串参数传递一个类名,
就可以得到这个类的所有信息,包括它所有的方法,和方法的详细信息。还可以实例化一
个对象,并通过查到的方法名来调用该对象的任何方法。这是因为Java的类在内存中除了
C 中也有的静态动态数据区之外,还包括一份对类自身的描述,也正是通过这描述中的信
息,才能帮助我们才运行时读取里面的内容,得到需要加载目标类的所有信息,从而实现
反射机制。大家有没有想过当我们需要得到一个JavaBean的实例的时候,怎么知道它有哪
些属性呢?再明显简单不过的例子就是自己写一个JavaBean的解析器:

a. 通过Class.forName(“Bean的类名”)得到Class对象,例如叫ABeanClass
b. 通过ABeanClass的getMethods()方法,得到Method[]对象
c. 按照规范所有get方法名后的单词就代表着该Bean的一个属性
d. 当已经知道一个方法名,可以调用newInstance()得到一个实例,然后通过invoke()方法将
方法的名字和方法需要用的参数传递进去,就可以动态调用此方法。

当然还有更复杂的应用,这里就不赘述,大家可以参考Class类和Method类的方法。

4. 坦言Synchronize的本质
Synchronize大家都知道是同步、加锁的意思,其实它的本质远没有大家想得那么复杂。声
明Synchronize的方法被调用的时候,锁其实是加载对象上,当然如果是静态类则是加在类
上的锁,调用结束锁被解除。它的实现原理很简单,仅仅是不让第二把锁再次被加在同一
个对象或类上,仅此而已。一个简单的例子足以说明问题:
class A{
synchronized void f(){}
void g(){}
}

当A的一个对象a被第一个线程调用其f()方法的时候,第二个线程不能调用a的synchronized方
法例如f(),因为那是在试图在对象上加第二把锁。但调用g()却是可以的,因为并没有在同
一对象上加两把锁的行为产生。
这样大家能理解了麽?明白它的原理能更好的帮助大家设计同步机制,不要滥用加锁

类别:默认分类 | 浏览(51) | 评论 (0)
 
 
网友评论:
发表评论:
姓 名:
网 址:
内 容:




     

©2008 CangZhuo