Java  杂谈(三)
        这已经笔者写的第三篇Java杂记了,庆幸前两篇一直得到论坛朋友们的支持鼓励,还望大家继续指正不足之处。笔者也一直渴望通过这样方式清醒的自审,来寻找自己技术上的不足之处,希望和共同爱好Java的同仁们一起提高。
        前两次分别讲述了关于jvm、jdk、jre、collection、classLoader和一些Design  Pattern的自我理解。这次仍然不准备开始过渡到j2ee中,因为觉得还有一些琐碎的j2se的问题没有总结完毕。
   
          1.  关于Object类理解
        大家都知道Object是所有Java类的基类,  意味着所有的Java类都会继承了Object的11个方法。建议大家去看看Object的  11个成员函数的源代码,就会知道默认的实现方式。比如equals方法,默认实现就是用"=="来比较,即直接比较内存地址,返回true  或者  false。而toString()方法,返回的串组成方式是??
        "getClass().getName()  +  "@"  +  Integer.toHexString(hashCode())"
        其实不用我过多的解释,大家都能看懂这个串的组成。接下来再看看hashCode():
        public  native  int  hashCode();
     
        由于是native方法,跟OS的处理方式相关,源代码里仅仅有一个声明罢了。我们有兴趣的话完全可以去深究它的hashCode到底是由OS怎么样产生的呢?但笔者建议最重要的还是先记住使用它的几条原则吧!首先如果equals()方法相同的对象具有相通的hashCode,但equals  ()对象不相通的时候并不保证hashCode()方法返回不同的整数。而且下一次运行同一个程序,同一个对象未必还是当初的那个hashCode()  哦。
        其余的方法呢?nofigy()、notifyAll()、clone()、wait()都是native方法的,说明依赖于操作系统的实现。最后一个有趣的方法是finalize(),类似C++的析构函数,签名是protected,证明只有继承扩展了才能使用,方法体是空的,默示什么也不做。它的作用据笔者的了解仅仅是通知JVM此对象不再使用,随时可以被销毁,而实际的销毁权还是在于虚拟机手上。那么它真的什么也不做麽?未必,实际上如果是线程对象它会导致在一定范围内该线程的优先级别提高,导致更快的被销毁来节约内存提高性能。其实从常理来说,我们也可以大概这样猜测出jvm做法的目的。

2.  关于重载hashCode()与Collection框架的关系
笔者曾经听一位搞Java培训多年的前辈说在他看来hashCode方法没有任何意义,仅仅是为了配合证明具有同样的hashCode会导致equals  方法相等而存在的。连有的前辈都犯这样的错误,其实说明它还是满容易被忽略的。那么hashCode()方法到底做什么用?
     
        学过数据结构的课程大家都会知道有一种结构叫hash  table,目的是通过给每个对象分配一个唯一的索引来提高查询的效率。那么Java也不会肆意扭曲改变这个概念,所以hashCode唯一的作用就是为支持数据结构中的哈希表结构而存在的,换句话说,也就是只有用到集合框架的  Hashtable、HashMap、HashSet的时候,才需要重载hashCode()方法,
这样才能使得我们能人为的去控制在哈希结构中索引是否相等。笔者举一个例子:
        曾经为了写一个求解类程序,需要随机列出1,2,3,4组成的不同排列组合,所以笔者写了一个数组类用int[]来存组合结果,然后把随机产生的组合加入一个HashSet中,就是想利用HashSet不包括重复元素的特点。可是HashSet怎么判断是不是重复的元素呢?当然是通过  hashCode()返回的结果是否相等来判断啦,可做一下这个实验:
        int[]  A  =  {1,2,3,4};
        int[]  B  =  {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()却是可以的,因为并没有在同一对象上加两把锁的行为产生。
        这样大家能理解了麽?明白它的原理能更好的帮助大家设计同步机制,不要滥用加锁。

PS:下篇笔者计划开始对J2ee接触到的各个方面来进行总结,谈谈自己的经验和想法。希望大家还能一如既往的支持笔者写下去,指正不足之处。
############################################################################################################# 
 不知道这个synchronized  和操作系统的读写锁有什么区别啊?

这个只能加一次锁吗?

【转】Java 杂谈(三)相关推荐

  1. java多线程三之线程协作与通信实例

    多线程的难点主要就是多线程通信协作这一块了,前面笔记二中提到了常见的同步方法,这里主要是进行实例学习了,今天总结了一下3个实例: 1.银行存款与提款多线程实现,使用Lock锁和条件Condition. ...

  2. Java的三种代理模式简述

    本文着重讲述三种代理模式在java代码中如何写出,为保证文章的针对性,暂且不讨论底层实现原理,具体的原理将在下一篇博文中讲述. 代理模式是什么 代理模式是一种设计模式,简单说即是在不改变源码的情况下, ...

  3. 区分 JVM 内存结构、 Java 内存模型 以及 Java 对象模型 三个概念

    本文由 简悦 SimpRead 转码, 原文地址 https://www.toutiao.com/i6732361325244056072/ 作者:Hollis 来源:公众号Hollis Java 作 ...

  4. 学习Java的三十三个建议

    学习Java的三十三个建议 1把Java当成一门新的语言学习(和C++差别很大,真的,我觉得和Delphi的Object Pas cal反而更像一点): 2看<Thinking in Java& ...

  5. java三个环境变量_java基础(一):我对java的三个环境变量的简单理解和配置

    首先说说java的三个环境变量:java_home,classpath,path java_home:jdk的安装路径[你一层一层点开安装路径,直到当前目录有一个bin目录,然后在地址栏里面右键单击复 ...

  6. Java的三种代理模式完整源码分析

    Java的三种代理模式&完整源码分析 Java的三种代理模式&完整源码分析 参考资料: 博客园-Java的三种代理模式 简书-JDK动态代理-超详细源码分析 [博客园-WeakCach ...

  7. java第三阶段源代码_有效Java第三版的源代码已更新为使用较新的功能

    java第三阶段源代码 那些已经阅读了有效Java 第三版的人可能知道与该书相关的源代码可以在GitHub上获得 . jbloch / effective-java-3e-source-code项目拥 ...

  8. 有效期判断功能 java_有效的Java第三版有哪些新功能?

    有效期判断功能 java 自从听说即将出版的有效Java 第三版以来,我一直想知道其中有什么新内容. 我假设将涵盖自Java 6以来引入Java的功能,的确如此. 但是,第三版Java开发人员经典版也 ...

  9. 有效Java第三版的源代码已更新为使用较新的功能

    那些已经阅读了有效Java 第三版的人可能知道与该书相关的源代码可以在GitHub上获得 . jbloch / efficiency-java-3e-source-code项目拥有1700多个星星,截 ...

  10. 有效的Java第三版有哪些新功能?

    自从听说即将出版的有效Java 第三版以来,我一直想知道其中有什么新内容. 我假设将涵盖自Java 6以来引入Java的功能,的确如此. 但是,第三版Java开发人员经典版也有一些其他更改. 在本文中 ...

最新文章

  1. 学习Key与Value的集合hashtable
  2. SpringBoot之CommandLineRunner,预先加载系统数据
  3. Kettle日常使用汇总整理
  4. 用Python实现归并排序
  5. 计算机安全专家建议:尽快为电脑升级打补丁
  6. 1037. 在霍格沃茨找零钱(20)
  7. c#中struct和class的区别
  8. 终于有人把项目搭建讲明白了!
  9. C# TabControl增加关闭按钮
  10. java home_JAVA_HOME配置
  11. 计算机模拟的概念,湍流概念及数值模拟方法
  12. 旷视6号员工范浩强:高二开始实习,“兼职”读姚班,25岁在CVPR斩获第四个世界第一...
  13. 第3章【思考与练习4】数据清洗,从studentsInfo.xlsx 文件的“Group1”表单中读取数据。数据填充,使用习题1的数据,使用列的平均值填充“体重”和“成绩”列的NaN数据。
  14. HTML5小游戏程序案例--冰桶挑战h5案例
  15. CS下载、安装以及简单使用
  16. BZOJ---4484:[Jsoi2015]最小表示【bitset】
  17. 微信小程序接入环信客服
  18. 初识网络原理——网络原理的基本概念
  19. 单片机c语言数码管程序,51单片机C语言程序(三)数码管
  20. 请编写一个程序,使用字典存储学生信息,学生信息包含学号和姓名,请根据学生学号从小到大输出学生信息

热门文章

  1. Leetcode 刷题笔记(二) —— 数组类型解题方法二:双指针法
  2. 通过命令行运行java出现错误: 找不到或无法加载主类 解决办法
  3. OPPO以技术推动产品 获专利数首次挺近前十
  4. bitnami下mysql配置-包含phpMyAdmin配置
  5. django发送邮件结合itsdangerous+celery+redis
  6. openstack nova调用libvirt,跟踪libvirt源码实例详解(cpu_mode及live_migrate 错误解决)...
  7. vSphere Replication:虚拟机的保护伞
  8. 南京铁道学院计算机应用,南京铁道职业技术学院铁道交通运营管理专业
  9. linux 交换机 进程,基于Linux系统交换机的进程升级研究
  10. java mysql存储图片_Java存储图片到Mysql