跟随高老爷子,重温java

  这几天,重读了高老爷子的java编程语言一书,就以博客为纸,做一些简记,有些凌乱,也不怕见笑了。另外顺带插一句,这一段时间重温了大学里的一些基础课程,觉得还都比较经典,受益也比较多。实用的书往往受益于一时,而有些书每一次翻起都会有些新的感受,建议大家有空的时候也可以多翻翻。

  本文写的是关于java的,也许不适合这里,但我还是喜欢这里的草根味道,当然也不全是,毕竟全草根是很难存活的,但相对其他园子就草根多了,还是喜欢趴在这块草地上乱划拉几下。

1、java语言是对c++语言的再思考,是对C++语言的选择、放弃和扩展。在当时新的需求要求更高的开发效率,要求更大众化。在很多应用方面,开发效率、简单易用已摆在执行效率的前面,对C++作规范和简化就成为时代的需要了。选择java有些戏剧,但只能说java的特性迎合了这种需要,反过来说是需要整合了java的特性。

2、垃圾收集,提高了开发效率,降低了执行效能。这一点在java前期客户端推广方面形成了致命的缺陷,即使有强大如Borland J支撑也不行,反而影响了一个非常有创造力、非常值得人们尊敬的一个公司命运,可惜了。有选择就有代价,这也是难免的。现在在执行效率方面的影响应该是不大了。

3、unicode字符串,大势所趋。

4、命名机制,引入包。更加明确了名称的查找方式。

5、接口独立命名,有利于约定与实现分离。在这里接口是一种程序约定,xml则是一种数据模式的约定。

6、异常处理,异常处理最早在哪儿开始使用?

7、byte code字节码解析执行,借用jvm实现了跨平台,同时也使语言具有安全性检查,防止对客户端机器造成破环,这是web应用的基本准则。再看看现在的js程序,采用了明码,你都看到了代码,总相信我的页面是安全的了,只是事实都如此吗?

8、隐式基础类Object,不同于C++,所有对象都来源于共同的超类,规范了类的行为,也为集合运算的简化提供了基础,由于前期版本没有模板,java集合类操作的对象都是Object,简化编程应该是高老爷子优先考虑的目标。

9、类的继承,类可以继承多个接口,但父类只能有一个,这也许是接口独立命名的一个原因,否则就没有办法区分了。

  多重继承在类的理论上是很需要的,但在实际使用上效果并不是很好,另外多继承可以用组合的方式间接解决,用起来不是很直接,扩展性却增加了。于是很多专家(不是砖家)就提出放弃多重继承,追求简单的高老爷子自然就接受了。

  一个事情的短板,可能在下个循环就变成了长板,因为人们想出了更好的解决方案,不知多重继承还会不会成为一种语言的介绍重点。

  类是为扩展性而来,而类的内存布局却影响了扩展性,java,C#部分解决了这个问题,在程序单元之间C#更多采用了属性,而js干脆采用map方式,但有意思的是,v8为提高js的执行效率, 反过来想尽办法,用内存布局来替换map,你看折腾不?。

  类的继承还有一个问题不太好解决,希望申明一个类继承了两个接口,而其中一个类已经实现了一个接口,接口体现的是一种约定,而类更多体现是一种实现,实现往往会包含一些多余的东西。要想全部从约定来继承,又不想对另外一个接口重新实现,在语法上是乎没有更简单的方法,只能采用以下两种方法,一种办法是把已实现类的方法重新引出一遍,在firefox的实现中有很多这样的代码,另外一种方法是引出接口对象。

  类和接口定义了一个事物的层次结构,而模板则定义一组事务的框架结构,能用类的地方基本上可以用模板,用模板的地方类不一定能用。模板是C++的利器,但器物太利了,很多人就会敬而远之。另外模板的程序大部分是明文、定义与实现混杂、太多技巧语义不直观,也应该是很多人不常使用模板的原因。但模板体现了静态语言实现动态特性的方法,同时模板定义了一组事务的框架结构,对于静态语言来說是一个很好的特性,丢弃模板在java上一个直接体现就是集合类不能限定为具体类型,而不能在出入栈时由编译器直接检查类型。但在当时,为了达到简单的目的,而且最初java是作为嵌入式设备的语言设计的, 高老爷子选择放弃模板是必然的,同样的理由也适用于宏定义。而作为后来者C#,对模板的功能作约束后作为语言特性,也是必然的,同样也包括宏。

10、类装载器,新语言或者这一代语言与C++相比,很大的一个特点是引入元信息,使得基本程序元可以反射,也为类装载提供了基础,毕竟C++是不能直接从字符串构建出一个对象,除非加上很多约定。而Web应用也需要类装载器,java、c#、xul都提供了这样的能力,顺便提一句,xul本身不出名、却有很多好的想法被wpf借用,并得到更好的发挥。

  装载器还有一个意想不到的用途是程序结构的解耦,这是设计框架最需要的特征,也是java框架的基本特色,java框架的繁荣这一点可以说功不可没,加上跨平台的特性(大家都知道这是从JVM引申出来),再加上提升性能的即时编译(这是元信息的引申),最终使java走向服务端,而客户端反而变成了补充。这样的一个局面,不知高老爷子开始的时候有没有预见到,只是在这本书上是没提到一笔。

  一种新的思路或设计,往往伴随着很多新的特性,而往往是这些特性中的一些特性决定着设计思路的命运,而原来追求的特性反而变轻了,是不是也是无心插柳柳成荫,只是没有原来的设计,也产生不出新的特性。

  对于java的客户端,通过Google公司的换心设计,提升了性能,在移动领域大兴其道,这样的情况在语言设计之初更是不会想到。

  俗话说,有得必有失,有意义的是,java框架中太多选择,反而让java框架选择和使用变得像写C++程序,需要很多的技术和技能。在这一点上.net框架反而更多继承了java设计之初所要求的简单、简便、高效的特性,我想这也是很多人选择.net的原因,就像当初许多人选择java,而不是C、C++。历史就像被扔了石头的水面,一圈套一圈,充满着戏剧。只是在前有狼、后有虎的情况下,微软如何扔包袱,轻装上阵,秉承其好斗性格,值得期待。

11、宏定义,为了简单java放弃了宏定义。而对于一些c或者C++大神来说,宏则是最爱,不信看看gcc中宏的运用,还有哪些跨平台开源代码中一层接一层的宏定义,宏定义可以满足C++大神对程序简单、简洁、不重复、高效的苛求,其实有时也只是满足一下新奇的嗜好。放弃了宏,可是剥夺了我们欣赏一些奇特代码的权利,另外也使java失去条件编译的能力。

12、对象引用,从简单角度,去除指针也是应该的,去除了指针,二级、三级指针也就没有了,这些都可以用数组来模拟。C和C++来源于汇编,一种实现往往有多种语法,而java对此则作了约束。

  老爷子特别提到所有函数参数都是传值的,对象传的是引用的拷贝,这样传入变量原来的值是不会被改变,而C++引用参数原来的值是可以被改变。这样是安全了,问题也来了,java的输出参数在哪里,还是压根就没有输出参数?另外还有一个问题,我的函数指针在哪里?

  由于对象变量是引用,等来等去还是引用,这就涉及到对象拷贝的问题,这倒好解决,java提供了clone的机制,但确实不像C++结构一个等号这么简单。

13、多线程,一个很好的特性,让多线程编程走入坦途,当时是一个很大的效率提高。只是人们现在更关注是CAP、MapReduce、NoSql,只能感叹挡不住的是时间。

14、goto语句,带点魔气的东西,一律进不了高老爷子的法眼。毕竟其他方式可以替换,影响也不会很大。看现在的流程程序,是否是节点goto出,节点goto进,看来魔气总是会挥发出来,包不住啊。另外假如维纳斯没有断臂?

15、数据流,提供了数据的虚拟接口,针对不同的源,应该都是都需要的,但这么多的对象看起来还是有点晕。

16、文档式注释,潜台词是程序员写程序接口文档方面比其他人员做得更好。

   简便、易用、安全应该是java语言设计的出发点,以此为基础引入了字节码、虚拟机、元信息、垃圾收集,并对C++的很多特性进行了规范和约束,并引伸出一些有用的新特性,迎合了时代对语言的需求。当然一种语言不可能一开始就很完美,而是在不停的演进中逐渐变得完整。有些约束现在看来有些过度,如宏、模板、输出参数、函数指针等,在新的版本及后来的C#语言中作了些放宽和调整,也是需要的,但在当时只能做这样的选择,否则反而达不到设计目标。

  对于程序员来说,有时去探究一下语言特性的来龙去脉,也不失为学习语言的好方法。多与语言及框架的设计者作一些思法上的交流,可以让自己更好、更深地掌握你所接触的语言和框架。没有一种语言、一种框架在设计之初是完美的,它反映了时代的一种需要。我们所面对的大牛也好、大神也好,跟我们一样、首先是程序员,没必要去膜拜,去思考、去责疑、去推敲,才是对他们最好的敬重。

  语言是多种特性的有效整合,云开发同样离不开多种语言的协同,融合是一种需要,也是能量所在,过多的门户观念其实没有必要。UML由很多图组成,每种图不管能力有多强,也只能表现事物的一个方面,要刻画一个整体,需要多图的协力和合作。

你可能感兴趣的:(java)