阅读551 返回首页    go 京东网上商城


一年纯手工打造的Java老A上册开始预售了

Java老A这本书写了很久昨天终于开始在china-pub、京东、天猫上开始预售了不过既然叫预售就肯定还没到货。


有兴趣的人可以去看看哈后续其它网站地址也会在这里公开

china-pub

https://search.china-pub.com/s/?key1=java%cc%d8%d6%d6%b1%f8&type=&pz=1

京东

https://search.jd.com/Search?keyword=Java%E7%89%B9%E7%A7%8D%E5%85%B5&enc=utf-8

天猫

https://list.tmall.com/search_product.htm?q=Java%CC%D8%D6%D6%B1%F8&type=p&vmarket=&spm=3.7396704.a2227oh.d100&from=mallfp..pc_1_searchbutton


关于本书内容请参考https://blog.csdn.net/xieyuooo/article/details/38373409

里面有本书的所有目录信息封面等。


关于写这本书的初衷和历史可参看

https://blog.csdn.net/xieyuooo/article/details/8915934

https://blog.csdn.net/xieyuooo/article/details/12493383


前期将手稿样章贴了一个小节到博客可参考

https://blog.csdn.net/xieyuooo/article/details/17452383


开始预售我顺便将前言、第一章部分内容贴出前言是写给读者朋友的大家可以参考下该书是否适合自己如下

本书书名为《Java特种兵》又名《Java老A》目的很简单希望作为读者朋友的你有一天能够成为一个单兵作战能力极度强悍的Java程序员。众所周知Java程序员多如牛毛我希望学习本书的读者有志者事竟成、出类拔萃练就一身好本领成为Java界的特种兵。


关于本书

冰冻三尺非一日之寒本书不是什么神功秘籍所以它无法让你在短时间内从一个小鸟变成一个牛人更加无法让你从牛人成为大师这本书是希望读者朋友能够在纠结的时候想起还可依赖它。因为本书不仅仅在讲解一些知识同时也包含了作者以及作者同事的一些工作经历以及工作经历中的那些痛苦与纠结我们希望在这本书的陪伴下你在纠结之时选择的不是放弃自我而是坚持到胜利的那一刻。

作者本人也不是什么牛人更加不是绝顶高手只能说我们经历的某些事情也许值得去分享这些内容不仅仅包含一些知识同时也包含了很多思想、方法和面对问题的态度注重功底和修为的提升。如果有一天你发现这本书带给你更多的是方法从而让你建立起自己的许多思路快速学习和成长那么本书的一个重要目的就达到了如果有一天你发现再去看某些“牛人秘籍”会比以前轻松和愉悦那么也许这本书有点小功劳。

本书不是什么代码大全也不是专门讲解某些指定的知识板块的书籍例如JVM并不会针对某些专门的知识板块去做过细的说明也不会去说明详细的API更加不会全面地说明它们的源码这是没有意义的。通过本书希望你能从内心认识到“知识无涯”我们总会遇到自己没有见过的问题需要学会的就是如何面对这些问题即如何去思考和定位如何去学习和成长。

在本书中可能会以各种“换位思考”的方式来探讨一些技术内容从技术本身的角度来讲侧重于讲解技术之中蕴藏的各种奥秘以及探索奥秘的一些思路而不是讲解一些技术的使用希望读者在这个过程中开始有意识地去理解知识的应有深浅之分并同时真正掌握Java基础提升自我的功底同时还能找到提升功底的方法。

本书中许多对话和探讨的模式适合像小说一样来静心品味我相信如果你能静心那么不论是初学者还是有一定功底的人都能从本书中受益。作者本人在刚进入大学的时候是一个连计算机是什么都不知道的人也曾经有过为了通过C语言考试而死记硬背代码的经历后来通过不断努力才有能力写出这本书。因此本书会结合当时胖哥从一个计算机届的“文盲”开始成长的过程中所拥有的一些“可爱”的思想经历如果你有类似的思想经历希望这本书能够帮助到你也同时希望你理解到只要你愿意你就一定行的

本书有的内容风格会偏于娱乐这些内容所描述的技术肯定不会那么严谨由于不严谨可能会让不同的读者产生仁者见仁、智者见智的情况。对于某些有着同样工作经历的人看来也许会有着发自内心的共鸣对于初学者可以是一个大概的形象理解。虽然书中的许多解释并不是技术点上的准确解释但我不希望初学者“小伙伴们”仅仅注重娱乐本身的话题而要想想这种娱乐的例子所带给自己的一些感性认识。

本书会谈到一些成长性的内容因此我们可以先大概定位下一些不同层次的人会怎样思考怎样做事情让大家有个形象上的认识。


 Java学习三段位

许多初学者就像是无头苍蝇四处乱撞什么都想学学了就丢而且喜欢钻牛角尖甚至没有独立思考的习惯遇到问题问再解决问题。他们经常会问“为什么我的东西在这好用在那不好用”因为你还根本不知道问题的原因当然不知道这么多的为什么了任何问题都需要定位分析再解决再总结。面对问题要静下心来通过自己对基础的认识来分析可能的原因然后逐步缩小范围再定位问题。如果抛一个错误就能知道原因那么直接设计一个答题的机器就可以了而不需要任何人为的介入。

学到一定程度的人懂得思考懂得换位思考能解决大多实际问题他们不仅仅能开始自己定位问题而且开始具有“前瞻性”思考一些问题未来可能存在的潜在情况也开始逐步关注一些内在原理。不过可能是艺高人胆大这些人有可能会犯一些不该犯的错误他们通常是一些十分优秀的程序设计者很多时候可能是为了展现自己的技术能力会将一些不值得去做的事情不断细化和优化或者去做一些别人做过的事情如果因为这样丢掉主业务则通常说它是过度优化、过度设计、重复制造。作者本身也有同样的亲身经历而很矛盾的在于是否真的是过度设计在不同的场景下会有不同的看法和评价因此这个阶段的同学通常会有一个纠结期。在这个阶段的人开始讲究内外双修也同样是一个积土成山、积水成渊的过程因为有一定的功底学习很多知识都很快在知识面上会有很大的突破在知识点上也会逐步加深可能在工作中不论是业务还是技术上都有了很多的选择被认为是工作能力很强的人。一些很“牛”的开发人员就会开始意识到很多代码如何去编写会更优雅、更加高效用更简单的代码搞定更多的问题但还未上升到系统级别和架构级别。

可能更高级别的人开始具有很强的全局观让系统全局更加具有可维护性和伸缩性系统性能良好稳定性十足能搞定各类架构、部署、规范化等相关的问题在某些领域上也是说话很有分量的人物。他们可能会花很多时间去写通用模型和设计将难题简单化解决大家解决不了的难题。通常会尽量让系统的维护变成一条配置或是几条简单代码但是可以顶得上一群人写一堆代码这就是特种兵程序员的“快”、“准”、“狠”、“稳”。

这里的各种级别仅仅是作者“自言自语”并不代表什么要做到没有级别在心中才能真正让自己快速成长。另外看了这些级别并不代表今天我是初学者明天将不好的习惯改掉后就“脱胎换骨”了也并不代表自己在某件小事情上有了大师的风范就代表自己是大师了。这些东西都是经历一些事情后才会形成一些自然意识我们只是有意识地去学习他们为什么会这样做事情为什么年轻人比老员工有活力但通常来讲“姜还是老的辣”。

本书读者对象

□ 适合对象

1有一定Java基础并希望能在Java技术上有所成长的人。

本书学习有一定门槛如果是初学者则可以先以书中的一些例子为引导希望了解为什么的时候再来看其中的解释。

2对于能静心看书的初学者可以迭代着看本书。

虽然有一定门槛不过初学者只要能静心迭代着读几次后你或许也能体会出里面有很多思想、方法、解决问题的手段、看问题的侧面甚至面对问题的心态那么也可以受益良多。

3本书是一个载体一个推崇自我修为、内外双修的载体修行看个人所以适合于想要以自我提升为主要目的的读者。

4工作一段时间对知识和发展的方向很迷茫甚至对某些观念也比较迷茫但是又渴望去解决这些问题渴望自己成长渴望自己能找到道路的人。

□ 不适合对象

1Java方面的高手和牛人因为这本书并不能助你从牛人变成大师。

2做客户端如Android或嵌入式的Java程序员因为书中大多内容是以服务器端Java来讲解的极少考虑客户端的问题。

3如果你对自己或周围的一切很绝望看到的所有东西都是邪恶、虚伪的也没有想过要让自己进步。

4希望这本书成为技术字典的同学不适合读因为这本书不是代码大全也不是知识点精准解释的汇聚更不是API的列表。

5希望系统性学习某些专业知识的同学不适合看本书因为本书讲解的是一种“碎片化”学习方式或者说是以一些小例子为基础进一步处理相关问题的方式。

如何阅读本书

作为书籍的作者希望读者能够快乐地学习到知识每天空余时间看看而不是一种压力面对技术拥有独自思考问题的能力而并非掌握某种技术本身通过轻松地接触很多知识并且能有所体会不断地去总结、抽象能得出自己的分析问题、解决问题的方法磨练出超越普通程序员的功底最终成为Java老A。

本书其实是一本Java的野书、杂谈会尽量用通俗易懂的方式来讲解一些复杂的问题和技术。不过这毕竟不是一本娱乐的书某些内容胖哥还是会说得比较严谨。书中除了讲解一些“功底类”的技术外大部分技术不会讲得太深大多只是抛砖引玉给你一个思路当你需要去接触更深的技术的时候在这本书中可能会有一个较为形象的例子供你参考也许就大概知道了如何去理解。若功底够好就会发现万变不离其宗一切都可以归于基础而且大多复杂的思路都源自于生活的灵感。

如果是初学者希望你不要期望每天看太多内容而是希望你看了后尽量去思考不用完全看懂每天能够有一个心得当你在实践中遇到某些问题开始拥有灵感时本书或许会印证这一切。

本书提到的技术仅仅是一个引导、一种探讨、一种思路在阐述一件事情好与不好的时候通常会以多种角度去看待问题的不同侧面再来说明为什么会有这样的经验同时也可能会探讨这些经验是否能够受用终身。因为技术的时代在不断革命现在的技术十分泛滥但都殊途同归我们要跟上时代又要归纳总结也许很多时候我们没有精力去学习所有的知识但有精力让自己提升学习能力从而来学习更多的东西也有精力来探索工作领域内的知识奥秘而前提是应当有探索奥秘的习惯以及足够的功底。

本书的目的在于个人成长极少谈到关于团队合作与规范化等方面的知识当然作为一个单兵作战能力极强的人应当有这方面的意识和思维即使本书中没有提及大家也应当去掌握。同时也请读者朋友注意本书所提倡的单兵作战能力并不是期望大家去做一个技术上的孤独者而是更好地去工作。

约定

□本书将采用HotspotVM 1.6作为讲解的例子可通过命令“java –version”得到JVM版本而测试的例子如果是在具体的OS环境下测试则会单独说明。书中也会提到JDK 1.7的内容相应的代码如果要运行也要选择JDK 1.7。

□本书中“部分例子”必须采用-server模式来运行和模拟尤其是第5章并发编程中的许多例子在例子中通常会有专门的备注和说明请读者注意参看。

□篇幅所限本书中的例子大多只是片段以说明实际的问题为主需要完整的例子请参看配书光盘中的相关demo信息书中的例子都有与之对应的实际代码除十分复杂的代码外从demo中获取的代码进行相关的配置后均可直接在对应平台上按照指定结果运行。

□本书的代码分源码和代码两种源码为第三方源码可以到官方网站下载参看书中会介绍源码的版本和思路并贴出部分关键源码的功能和设计思路。

□本书从第2篇开始每一篇都会有“致读者言”目的是让读者更好地了解这部分内容应该从何种角度去理解它会说些什么会给你带来什么你为什么需要这些。

□网络上大家都称作者为“小胖哥”或“胖哥”所以在本书中也会以这两个称呼作为作者本人的代名词。

内容简介

本书分上下册总共5篇上册两篇内容分别是功底篇和源码篇强调个人修为的提升也是本书主旨所在希望能帮助各位读者朋友提升“功力”下册中将基于上册的内容融入设计、实现的细节。

上册

第1篇 Java功底篇

建议所有本书的读者朋友都读下本篇的内容所谓“练武不练功到老一场空”你是否要成为一个老A级程序员功底的提升是十分重要的通过对第1篇的学习希望读者能知道如何验证自己的功底如何提升自己的功底而能提升多少完全要靠你自己的属性哦

第1章从简单的角度来验证功底通过一些简单的例子来说明我们应当如何去掌握Java的基础同时也包含一个“老A级程序员”除功底外还需要有面对逆境的心态。

第2章和第3章分别介绍关于计算机的工作原理和Java虚拟机的基础知识。胖哥认为一个优秀的Java程序员应当知道自己的程序在计算机内部是如何运行的更需要知道虚拟机是如何运行的效率对比怎样此好比“习武之人需要知道何为武学”。

第4章讲解Java通信在了解了运行基本原理后你应当了解很多网络交互已经被Java的框架包装得不再像通信程序了就像是“被装修后的房子你不再知道房屋本身是用什么建造的”。但如果你是老A就应当知道这些这样才能知道遇到各种怪异的问题时如何去解决你会发现“一切源自基础偶然问题隐藏必然”。

第5章讲解Java并发如果读者朋友确实遇不到则可以跳过但要成为Java的老A这应该算是基础知识老A应该知道Java并发是怎么样的。除了客户端程序及单片机等Java并发程序处理其实无处不在就好比“一个城市的交通很多的车辆需要通信应当如何调度来提高流量避免交通事故”。

第6章讲解数据库知识大部分程序员都应该使用过数据库、文件通过学习第4章通信方面的内容应该会有一些概念但是面对存储你是否想要了解一些内在了解一个程序员所需要知道的内在这样可能会使得你的工作更加得心应手。说了这么多你是否发觉学习Java为何要了解如此多的东西是的你需要知道“多个门派的武学面对不同的思想碰撞来切磋才会有更多的体会”。作为一个老A才会拥有单兵作战能力极强的作战素质。

第2篇 源码篇

达到一定程度的程序员一般会开始对实现本身感兴趣想了解为什么了解别人是如何设计和实现的。

起初在面对框架的时候可能会去猜测或测试它是如何实现的但逐渐发现猜测和测试并不那么靠谱因为版本和环境影响因素太大我们开始想要知道一些内在看源码成为一个必然。源码面前没有秘密可言看过源码你会对问题定位和编写代码拥有自信开始对技术本身有量化的认识。

本篇并不是网络天下源码也不会对某种源码做全面讲解而是通过阅读源码来说明我们应当如何阅读源码。

在本篇开始部分会先介绍为何要阅读源码讲解哪些源码如何阅读源码请有疑问的小伙伴们关注一下哦。

第7章讲解源码基础说明Java常见的框架基础知识主要包括反射、AOP、ORM、Annotation和配置文件的原理。在这里不仅仅会阐述技术本身同时也会联系一些实际框架的可能实现方法。老A一定要“知其然知其所以然”。

第8章和第9章分别讲解JDBC、Spring的源码这里不会说明这些三方包的所有源码和关键点。但通过几种不同类型的框架源码希望读者能体会源码之中的“思维方式、设计、架构”以及了解到不同源码的区别所在。虽然区别很多但如果你有一些“百川纳海、源自同门”的感受那么小伙伴们就成长了很多。

第10章是对第2篇的知识总结在阅读源码后不是读完就完了而是应当有所体会。通过对源码基础知识的初步了解和对一些源码的阅读我们逐步有能力在接触一个自己从未见到的框架时可以大概知道它的大致内在并且大多数情况下可以轻松搞定它即使有一定难度也会从根本的角度去看待这些技术问题进一步快速地通过看它的代码了解内在而不会被浮于表面的使用所迷惑。这就好比虽然魔术师的表演眼花缭乱但是在他们同行眼中都是知根见底的因为我们也是专业的所以不应当被一些东西所迷惑。

下册

第3篇 设计篇

老A虽然不像军师那样“运筹帷幄之中决胜千里之外”但也同样需要有全局的部署思想对临场应变以及撤退方案和路径要有全局把控能“在万军之中取上将首级”使用最低牺牲得到最高的成果。

在设计篇中胖哥希望给你带来的不仅仅是现有老A的技术也包含了他们的许多思想。既然是思想自然是结合场景最佳它需要融入老A的智慧不限于表达的形式因为这些形式只是一种思想传承的载体。

第1章中胖哥会用平时工作中的例子说明一些常用的设计模式但并不会将Java所有的设计模式全部详细讲解因为这不是本书的主旨而且那样并没有多大意义。在实际的应用中场景是非常重要的变化远远大于这些设计模式本身所提供的“招式”。模式本身提供一种建议性的设计方法就好比武学中的“招式是死的人是活的”不同年龄段修炼同样的武学与不同的对手较量不论是招式的顺序还是临场的动作都会有很大的变化。如果在实战对决中一再用套路来较量就会被套路牵引着走也会被对手打乱节奏而套路本身给我们提供了一种处理场景的方法灵活应用才能用以实战这样才能达到“无招胜有招”的境界。

第2章和第3章介绍两个实例的设计它们是两种完全不同类型的程序在这个过程中尝试应用设计模式中的一些知识和思路也就是需要知道如何利用招式来对敌。但大家不要仅仅局限于这两章所给出的例子因为实际场景可以千变万化针对自己所遇到的场景需要去揣摩和思考。我们的例子通常不会写到实现部分到设计部分基本结束希望你能理解到“思想和方法应当源于生活和自然”。

第4篇 实现篇

在原计划中胖哥并没有打算写关于“实现”方面的内容不过胖哥发现在实际工作中小白“童鞋”们所面对的可能最多是实现于是增加了这部分内容。但是在实现篇并不是拿一个业务实例来写代码谈什么呢

第4章谈谈项目中各种工作人的交互、开发模式、心态、技术上的思维方式、一些优化思路。第5章简单谈谈UI的一些用途、繁杂的点在那里。第6章谈谈实际工作中经常会遇到的“坑”这些坑不容易被发现但是我们经常容易掉进去希望大家知道的不仅仅是这些坑而是通过这些坑了解到众多技术都是一把“双刃剑有好处必有坏处”只有最佳的场景选择最合适的技术学会如何去量化与选择同时需要了解到现在的工作对个人素质的要求越来越高。

第5篇 扩展篇之论道

扩展篇为杂谈也是论道篇读者可以先看第5篇的内容本篇是对知识面和思想的一个扩展。一个老A应当知道业界的一些技术所谓“知己知彼百战百胜”接触任何一种问题都要有相应的解决方案。

第7章和第8章以走马观花的方式来介绍一些集群知识、分布式知识但并不意味着实际的技术和走马观花那样简单。作为老A程序员胖哥认为需要知道这些这样才能更好地做好一些事情或者说有机会去做更有挑战的事情。也许你今天用不到这些但当你用到时便能更加得心应手。

第9章讲解技术量化与权衡的一些事情会谈一些时间管理、团队合作、过度优化、预知问题、不同项目的实现思路等。这里阐述的中心思想是我们应当在技术追求的道路上考虑各种成本与价值的问题从个人做起再看看团队协作。

第10章是完结章主要是探讨一些心态以及励志有兴趣的小伙伴们可以看看没有兴趣的无须关注本章。现代老A除了素质过硬外更要拥有智慧智慧包含了丰富的知识面同时也包含了对于世界的理解静心做好当下有机会去做好创新在芸芸众生之中脱颖而出。




上面部分为前言的主要部分下面贴一点点第一章的小内容大家可以参考下是否适合自己的口味


1.1  String的例子见证下我们的功底

哇塞第1节就开始讲代码例子受不了啦胖哥你坏死了所有的书第1节都是写这个领域有什么东西的。

哈哈小胖哥天生就是个逆天之人哦希望你能先实践有了感性认识后再进行理论了解内在。

下面的代码改编于网络牛人的一段程序先看代码清单1-1。

代码清单1-1  一段String的比较程序

private static void test1() {

    String a = "a" + "b" +1;

    String b = "ab1";

    System.out.println(a == b);

}

胖哥你是不是考我智商呀我们平时对比两个对象不是用equals()吗老师告诉我两个字符串用等号是匹配不了的结果应该是false吧。那么结果到底是多少呢

运行结果

true

什么竟然是true为什么是true这是要逆天吗这小段程序彻底颠覆了我的经验和老师教我的真理“我和我的小伙伴们惊呆了……”

胖哥告诉你这不能怪老师老师带进门修行靠个人

也许有朋友做出了true或猜出了true那么可否知道原因呢如果你知道那么本节跳过无须再看如果还不知道就听听胖哥给你说说他所理解的原因。

要理解这个问题你需要了解些什么

◎关于“==”是做什么的

◎ equals呢

◎ a和b在内存中是什么样的

◎编译时优化方案。

下面的内容会很多现在我们可以站起来简单运动一下端一杯咖啡慢慢解读下面的内容。


1.1.1  关于“==”

首先要知道“==”用于匹配内存单元上的内容其实就是一个数字计算机内部也只有数字而在Java语言中当“==”匹配的时候其实就是对比两个内存单元的内容是否一样。

如果是原始类型byte、boolean、short、char、int、long、float、double就是直接比较它们的值。这个大家应该都清楚这里不再详谈。

如果是引用Reference比较的就是引用的值“引用的值”可以被认为是对象的逻辑地址。如果两个引用发生“==”操作就是比较相应的两个对象的地址值是否一样。换一句话说如果两个引用所保存的对象是同一个对象则返回true否则返回false如果引用指向的是null其实这也是一个JVM赋予给它的某个指定的值。

理解寓意大家各自拿到了一个公司的offer现在我们看看哪些人拿到的offer是同一个公司的。

1.1.2  关于“equals()”

equals()方法首先是在Object类中被定义的它的定义中就是使用“==”方式来匹配的这一点大家可以参看Object类的源码。也就是说如果不去重写equals()方法并且对应的类其父类列表中都没有重写过equals()方法那么默认的equals()操作就是对比对象的地址。

equals()方法之所以存在是希望子类去重写这个方法实现对比值的功能类似的String就自己实现了equals()方法。为什么要自己去实现呢因为两个对象只要根据具体业务的关键属性值来对比确定它们是否是“一致的或相似的”返回true|false即可。

迷惑1equals()不就是对比值的吗为何说相似

答曰一日偶遇怪侠“蜗牛大师”一枚赐予神剑于数人猎人将其用于打猎农夫将它用于噼材将军用它保家卫国侠客用它行侠仗义、惩奸除恶等等。

例如在对比一些工程的图纸尺寸的时候由于尺寸都会存在细节误差可以认为宽度和高度比较接近就可以返回true而不一定非要精确匹配。另外图纸纸张的属性除了长度、宽度外还有如名称、存放位置、卷号等属性但是我们可能只需要对比它的长度与宽度在这个范围内其余的属性不会考虑。也就是说两个对象的值是否相同是自己的业务决定的而不是Java语言来决定的。

感悟变通让标准变为价值给你一种思想和标准你可以有不同的使用不能死扣定理我们要解决问题

迷惑2equals()重写后一般会重写hashCode()方法吗

要说明这个问题我们先要补充一些概念。

Java中的hashCode是什么——hashCode()方法提供了对象的hashCode值它与equals()一样在Object类中提供不过它是一个native本地方法它的返回值默认与System.identityHashCode(object)一致。在通常情况下这个值是对象头部的一部分二进制位组成的数字这个数字具有一定的标识对象的意义存在但绝不等价于地址。

hashCode的作用——它为了产生一个可以标识对象的数字不论如何复杂的一个对象都可以用一个数字来标识。为什么需要用一个数字来标识对象呢因为想将对象用在算法中如果不这样许多算法还得自己去组装数字因为算法的基础是建立在数字基础之上的。那么对象如何用在算法中呢

例如在HashMap、HashSet等类似的集合类中如果用某个对象本身作为Key也就是要基于这个对象实现Hash的写入和查找那么对象本身如何能实现这个呢就是基于这样一个数字来完成的只有数字才能真正完成计算和对比操作。

hashCode只能说是标识对象因此在Hash算法中可以将对象相对离散开这样就可以在查找数据的时候根据这个key快速地缩小数据的范围。但不能说hashCode值一定是唯一的所以在Hash算法中定位到具体的链表后需要进一步循环链表然后通过equals()来对比Key的值是否是一样的。这时hashCode()与equals()似乎就成为“天生一对”。换句话说一个是为了算法快速定位数据而存在的一个是为了对比真实值而存在的。

与equasls()类似hashCode()方法也可以重写重写后的方法将会决定它在Hash相关数据结构中的分布情况所以这个返回值最好是能够将对象相对离散的数据。如果发生一个极端的情况即hashCode()始终返回一个值那么它们将存在于HashMap的同一个链表中将会比链表查询本身还要慢。

在JDK 1.7中Hash相关的集合类对使用String作为Key的情况不再使用hashCode方式而是有了一个hash32属性其余的类型保持不变。

换个思路hashCode()与equals()并不是必须强制在一起如果不需要用到这样的算法也未必要重写对应的方法完全由你自己决定没有语法上强制的规约。

寓意此好比宝剑是否需要有剑鞘宝贝是否需要有宝箱雄性是否必须需要雌性地球是否需要有月亮

而并非是树是否需要土壤生命是否需要食物鱼儿是否必须需要水世界是否需要阳光

感悟一切在于场景与需求十分需要但也可以在某些情况下放弃。

有人说对比两个对象是否一致可以先对比hashCode值再对比equals()。

这似乎听上去挺有道理的但是胖哥本人可并不这么认为为什么呢胖哥认为hashCode值根本不是为了对比两个对象是否一致而存在的可以说它与两个对象是否一致“一点关系都没有”。

假如你希望对比两个对象是否是同一个对象则完全可以直接用“==”来对比而不需要用hashCode()因为直接对比地址值说明两个对象是否为同一个对象才是最靠谱的。另外默认的hashCode()方法还会发起native调用并且两个对象都会分别发起native调用native调用的开销也是不小的。

假如不是对比地址而是对比值自然就需要对象中的某些属性来对比。拿String类型的对象来讲如果调用某个String对象的hashCode()方法它至少会在第1次调用这个方法时遍历所有char[]数组相关元素来计算hashCode值这里之所以说至少是因为这个String如果并发调用hashCode()方法则可能被遍历多次遍历过程中还需要外加一些运算。如果对比的两个对象分别获取hashCode自然两个String对象都会分别遍历一次char[]数组。

即使hashCode一样了也同样证明不了这两个String是一样的这个hashCode是根据char[]数组的值算出来的不同的String完全可以算出一样的值还得再次循环两个String中所有的字符来对比一次才能证明两个对象是一样的。其实遍历了两个char[]数组已经是最坏的情况了equals()还未必会这样做在后文的图1-2中会详细说明。

换一个角度来讲如果是两个其它的自定义类型的对象不是String类型的对象之间判定出来hashCode不一样也不能说它们的值不一样有可能equals()匹配的是一个综合值与hashCode一点关系都没有还是要进行equals()这样绕来绕去往往是把简单问题复杂化了。

equals()内部要怎么做就去怎么做嘛想要优化完全可以像JDK自带的许多类那样先对比一些简单的属性值再对比复杂的属性值或者先对比业务上最快能区分对象的值再对比其它的值或者先对比地址、长度等处理方式将那些不匹配的情况尽快排出。

有人说重写后的hashCode()内部操作确实比equals()简单许多倍其实这个动作判定也是可以放在equals()方法的第1步中来完成的无需外部程序关注。

补充String的equals()方法中默认就要先对比传入的对象与当前的this是不是同一个对象。在HashMap等集合类的查找过程中也不是单纯的equals()也会先对比两个对象是不是同一个对象。

好累休息休息左三圈、右三圈再来看看胖哥为你做解读

a和b的内存情况是什么样的

回到“代码清单1-1”的例子中其中的等号说明a和b是指向同一块内存空间的就像两个人拿到同一个公司的Offer一样他们像什么呢见图1-1“死冤家又在一起了”

图1-1  两个冤家又拿到同一个公司的Offer

为什么a、b两个引用都引用到同一块空间了呢请看1.1.3节的内容解释不过在这一节中我们先感性认识下JVM的一些“东东”在第3章中会有更详细的介绍。小伙伴们不要着急我们一步一步来学习。

1.1.3 编译时优化方案

a引用是直接赋值的b引用是通过“+”赋值的a和b两个引用为什么会指向同一个内存单元这就是JVM的“编译时优化”。如此神奇小伙伴们惊呆了吧

当编译器在编译代码String a ="a" + "b" + 1;时会将其编译为Stringa = "ab1";。

为何因为都是“常量”编译器认为这3个常量叠加会得到固定的值无须运行时再进行计算所以就会这样优化。

疑惑编译器为何要做此优化

寓意“小胖”说我的报销单写好了并盖章了“小明”说我的也OK了那么就合并一起邮寄报销单吧。“小锐”说我的快写好了不过还没盖章那你写好后再说吧。

寓意为提升整体工作效率和节约资源能提前做的事情就提前做。我们自己设计一种平台或语言的时候是否会考虑这些呢

补充编译器类似的优化还有许多在后文中会有介绍例如当程序中出现int i = 3 * 4 + 120时并不是在实际运行时再计算i的值而是在编译时直接变成了i= 132。

容易出错JVM只会优化它可以帮你优化的部分它并不是对所有的内容都可以优化。例如就拿上面叠加字符串的例子来说如果几个字符串叠加中出现了“变量”即在编译时还不确定具体的值是多少那么JVM是不会去做这样的编译时合并的。而JVM具体会做什么样的优化不做什么样的优化需要我们不断去学习才能把工作做得更好。

同理证明的道理String的“+”操作并不一定比StringBuilder.append()慢如果是编译时合并就会更快因为在运行时是直接获取的根本不需要再去运算。同理千万不要坚定地认为什么方式快、什么方式慢一定要讲究场景。而为什么在很多例子中StringBuilder. append()比String的“+”操作快呢在后文中胖哥会继续介绍原因。


====>篇幅所限就贴这些吧。


PS

如果一些小伙伴在试读样章、前言后感觉本书真的很适合自己但是个人经济方面存在压力例如还在待业找工作、学生之类那么可以联系小胖小胖可以掏钱买这本书送给相应的小伙伴这方面不要觉得不好意思为求知没什么大不了的小胖觉得如果自己的书能帮助到别人内心也会很开心的到目前小胖也送书给不少有类似需求的小伙伴了

最后更新:2017-04-03 05:39:56

  上一篇:go centos 正确 安装 jdk
  下一篇:go $#,$?,$!等说明