《Java编程思想》--面向对象和JVM基础

1.java中的4种访问制权限

(1).public 最大访问控制权限,对所有的类都可见。

(2).protect 同一包可见,不在同一个包的所有子类也可见。

(3).default 包访问权限,即同一个包中的类可以可见,默认不显式指定访问控制权限时就是default包访问权限。

(4).private 最严格俄访问控制权限,仅该类本身可见,对外一切类都不可以访问(反射机制可以访问)。

非内部类的访问控制权限只能是默认的包访问权限或者是public的,不能是protected和private的。内部类的访问控制权限可以是protected和private。

Java只处理public和protected访问控制权限成员的文档注释,private和默认的包访问控制权限成员的文档注释将被忽略。

2.面向对象编程中两种对象组合方式——is-a 和 has-a 

(1).is-a组合

一个类继承具有相似功能的另一个类,根据需要在所继承的类基础上进行扩展。

优点 具有共同属性和方法的类可以将共享信息抽象到父类中,增强代码复用性,同时也是多态的基础。

缺点 子类中扩展的部分对父类不可见,另外如果共性比较少的时候使用继承会增加冗余代码。

(2).has-a组合

has-a组合是在一个类中引用另一个类作为其成员变量。

优点 可扩展性和灵活性高。在对象组合关系中应优先考虑has-a组合关系。

缺点 具有共性的类之间看不到派生关系。

3.多态 

在面向对象编程中,子类中拥有和父类相同方法签名的方法称为子类方法覆盖父类方法,当调用子类方法的某个操作时,不必明确知道子类的具体类型,只需要将子类类型看作是父类的引用调用其操作方法,在运行时,JVM会根据引用对象的具体子类类型而调用应该的方法,这就是多态。 多态的基础是java面向对象编程的晚绑定机制。

编程中有如下两种绑定机制:

(1).早绑定 一般在非面向对象编程语言中使用,在程序编译时即计算出具体调用方法体的内存地址。

(2).晚绑定 面向对象编程语言中经常使用,在程序编译时无法计算出具体调用方法体的内存地址,只进行方法参数类型和返回值类型的校验,在运行时才能确定具体要调用方法体的内存地址。

4.java单继承的优点

相比于C++的多继承,java只支持类的单继承。java中的所有类的共同基类是Object类,Object类java类树的唯一根节点,这种单继承有以下好处:

(1).单继承可以确保所有的对象拥有某种共同的特性,这样对于JVM虚拟机对所有的类进行系统级的操作将提供方便,所有的java对象可以方便地在内存堆栈中创建,传递参数也变的更加方便简单。

(2).java的单继承使得实现垃圾回收器功能更加容易,因为可以确保JVM知道所有对象的类型信息。

5.选择容器对象两个原则

(1).容器所能提供不同的类型的接口和外部行为是否能够满足需求。

(2).不同容器针对不同的操作效率不同。

 6.类型转换

Java中有两种常见的类型转换:

向上类型转换(upcast)和向下类型转换(downcast)

(1).向上类型转换(upcast)

向上类型转换是将子类对象强制类型转换为父类类型,经典用法是面向对象的多态特性。向上类型转换时,子类对象的特性将不可见,只有子类从父类继承的特性仍然保持可见,向上类型转换时编译器会自动检查是否类型兼容通常是安全的。

(2).向下类型转换

向下类型转换是将父类类型强制转换为子类类型,转换过后父类中不可见的子类特性又恢复可见性,向下类型转换时,编译器无法自动检测是否类型兼容,往往会产生类型转换错误的运行时异常,通常不安全。

7.java中5个存放数据的地方

(1).寄存器(Registers)

位于CPU内部,是速度最快的存储区,但是数量和容量有限。在java中不能直接操作寄存器。

(2).栈(Stack)

栈位于通用随机访问存储器 (RAM内存) 中,通过处理器的栈指针访问,栈指针从栈顶向栈底分配内存,从栈底向栈顶释放内存。栈是仅次于寄存器的速度第二快的存储器,在java程序中,一般的8种基本类型数据和对象的引用通常存放在栈内存中,不通过new关键字的字符串对象也是存放在栈的字符串池中。栈的优势是存取速度比堆要快,仅次于寄存器,栈数据可以共享。但缺点是存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。

(3).堆(Heap)

也是位于通用随机访问存储器 (RAM内存)中的共享内存池。Java的堆是一个运行时数据区,类的对象从中分配空间,凡是通过new关键字创建的对象都存放在堆内存中,它们不需要程序代码来显式的释放。堆是由垃圾回收来负责的,堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是由于要在运行时动态分配内存,存取速度较慢。

(4).常量存储器(Constant storage)

java中的常量是存放在系统内嵌的只读存储器中(read-only memory,ROM)的。

(5).非随机存储器(Non-RAM storage)

对于流对象和持久化对象,通常存放在程序外的存储器如硬盘。

8.java中赋值运算

基本类型赋值是直接复制值,赋值操作后相互不影响。 引用类型赋值是复制引用值,相当于给对象取一个别名,赋值之后两个引用指向同一个引用对象,相互之间有影响。 在Java中,向方法传递引用类型参数会改变参数的值,不让参数受到影响的解决方法,在方法内首先先将引用克隆一份,然后操作克隆的对象。

9.移位运算 

左移运算符<< 将比特位左移指定位数,右边部分补0,左移一位相当于乘2。

右移运算符>> 将比特位右移指定位数,如果是正数,左边第一位(符号位)补0,其余位补0,如果是负数,左边第一位补1,其余位补0。右移一位相当于除2。

无符号右移运算符>>> 将比特位右移指定位数,不论是正数或者负数,左边移除位统统补0。

 10.java中比int类型小的原始类型(char、byte、short)进行数学运算或者位运算时,数据类型首先转换成int类型然后进行相应的运算。

11.方法重载(overloading)方法同名,参数列表不同称为方法重载,注意方法的返回值类型不同不能作为方法重载。

12.java中的析构函数

Java中没有像C/C++的析构函数,用来销毁不用的对象是否内存空间,只有以下三个方法用于通知垃圾回收器回收对象。

(1).finalize( )只是通知JVM的垃圾收集器当前的对象不再使用可以被回收了,但是垃圾回收器根据内存使用状况来决定是否回收。 finalize()最有用的地方是在JNI调用本地方法时(C/C++方法),调用本地方法的析构函数消耗对象释放函数。

(2). System.gc()是强制析构,显式通知垃圾回收器释放内存,但是垃圾回收器也不一定会立即执行,垃圾回收器根据当前内存使用状况和对象的生命周期自行决定是否回收。

(3).RunTime.getRunTime().gc()和System.gc()类似。

注意,这三个函数都不能保证垃圾回收器立即执行,推荐不要频繁使用。

13.垃圾回收器原理

(1).引用计数(ReferenceCounting)垃圾回收算法

一种简单但是速度较慢的垃圾回收算法,每个对象拥有一个引用计数器(Reference Counter),当每次引用附加到这个对象时,对象的引用计数器加1。当每次引用超出作用范围或者被设置为null时,对象的引用计数器减1。垃圾 回收,器遍历整个对象列表,当发现一个对象的引用计数器为0时,将该对象移出内存释放。

引用计数算法的缺点是,当对象环状相互引用时,对象的引用计数器总不为0,要想回收这些对象需要额外的处理。 引用计数算法只是用来解释垃圾回收器的工作原理没有JVM使用它实现垃圾回收器。 引用计数的改进算法任何存活的对象必须被在静态存储区或者栈(Stack)中的引用所引用,因此当遍历全部静态存储区或栈中的引用时即可以确定所有存活的对象。每当遍历一个引用时检查该引用所指向的对象同时检查该对象上的所有引用没有引用指向的对象和相互自引用的对象将被垃圾回收器回收。

(2).暂停复制(stop-and-copy)算法

垃圾回收器的收集机制基于任何一个存活的对象必须要被一个存储在栈或者静态存储区的引用所引用。 暂停复制的算法是程序在运行过程中首先暂停执行把每个存活的对象从一个堆复制到另一个堆中已经不再被使用的对象被回收而不再复制。

暂停复制算法有两个问题:

a.必须要同时维护分离的两个堆需要程序运行所需两倍的内存空间。JVM的解决办法是在内存块中分配堆空间复制时简单地从一个内存块复制到另一个内存块。

b.第二个问题是复制过程的本身处理当程序运行稳定以后只会产生很少的垃圾对象需要回收。如果垃圾回收器还是频繁地复制存活对象是非常低性能的。

JVM的解决方法是使用一种新的垃圾回收算法——标记清除(mark-and-sweep)。

一般来说标记清除算法在正常的使用场景中速度比较慢但是当程序只产生很少的垃圾对象需要回收时该算法就非常的高效。

(3).标记清除(mark-and-sweep)算法

和暂停复制的逻辑类似标记清除算法从栈和静态存储区开始追踪所有引用寻找存活的对象。当每次找到一个存活的对象时,对象被设置一个标记并且不被回收。当标记过程完成后,清除不用的死对象释放内存空间。 标记清除算法不需要复制对象所有的标记和清除工作在一个内存堆中完成。

注意:SUN的文档中说JVM的垃圾回收器是一个后台运行的低优先级进程,但是在早期版本的JVM中并不是这样实现的,当内存不够用时,垃圾回收器先暂停程序运行然后进行垃圾回收。

(4).分代复制(generation-copy)算法

一种对暂停复制算法的改进,JVM分配内存是按块分配的,当创建一个大对象时,需要占用一块内存空间,严格的暂停复制算法在释放老内存堆之前要求把每个存活的对象从源堆拷贝到新堆,这样做非常的消耗内存。 通过内存堆垃圾回收器可以将对象拷贝到回收对象的内存堆中,每个内存块拥有一个世代计数(generation count)用于标记对象是否存活。每个内存块通过对象被引用获得世代计数,一般情况下只有当最老的内存块被回收时才会创建新的内存块,这主要用于处理大量的短存活周期临时对象回收问题。一次完整的清理过程中,内存块中的大对象不会被复制,只是根据引用重新获得世代计数。

JVM监控垃圾回收器的效率:

当发现所有的对象都是长时间存活时,JVM将垃圾回收器的收集算法调整为标记清除;当内存堆变得零散碎片时,JVM又重新将垃圾回收器的算法切换会暂停复制。这就是JVM的自适应分代暂停复制标记清除垃圾回收算法的思想。

14.java即时编译技术(JIT)

JIT技术是java代码部分地或全部转换成本地机器码程序,不再需要JVM解释,执行速度更快。 当一个”.class”的类文件被找到时,类文件的字节码被调入内存中,这时JIT编译器编译字节码代码。

JIT有两个不足:

(1).JIT编译转换需要花费一些时间,这些时间贯穿于程序的整个生命周期。

(2).JIT增加了可执行代码的size,相比于压缩的字节码,JIT代码扩展了代码的size,这有可能引起内存分页进而降低程序执行速度。 对JIT不足的一种改进技术是延迟评估(lazy evaluation),其基本原理是字节码并不立即进行JIT编译除非必要,在最近的JDK中采用了一种类似延迟JIT的HotSpot方法对每次执行的代码进行优化,代码执行次数越多速度越快。

15.Java中的高精度数值类型

BigInteger和BigDecimal是java中的高精度数值类型,由于它们是用于包装java的基本数据类型,因此这两个高精度数值类型没有对应的原始类型。

(1).BigInteger支持任意精度的整数,即使用BigInteger可以表示任意长度的整数值而在运算中不会因为范围溢出丢失信息。

(2).BigDecimal支持任意精度的固定位数浮点数,可以用来精确计算货币等数值。 普通的float和double型浮点数因为受到小数点位数限制,在运算时不能准确比较,只能以误差范围确定是否相等而BigDecimal就可以支持固定位数的浮点数并进行精确计算。

16.Java中赋值运算

(1).原始类型赋值运算

8种原始数据类型赋值运算。原始类型赋值运算后无论改变赋值运算符那一边的值都不会影响赋值运算符 另一边的值。

(2).引用类型的赋值运算

除了8中原始数据类型外所有的数据类型都是对象类型,对象类型的赋值运算是操作引用,如a=b,把b引用赋值给a引用,即原本b引用指向的对象现在由a和b引用同时指向。 引用赋值运算符又叫别名运算符,即它相当于给引用对象取了一个别名,其实引用的还是同一个对象。 引用类型的赋值运算,如果赋值运算符任意一边的引用改变了被引用对象的值,赋值运算符另一边的引用也会受影响。

时间: 2024-11-01 10:29:13

《Java编程思想》--面向对象和JVM基础的相关文章

java编程思想-基础

interface: 方法默认为public:成员变量默认 static and final 对象数组的定义:理解? 多接口继承:可以多个接口,但只有一个具体类,具体类在前面 自:多接口继承时,来自不同接口的同名方法怎么处理呢? java重载不能依靠返回类型加以区分(C++可以),也不能依靠checked 异常类型区分 变量定义中的系列定义(逗号隔开):变量名 = 值,其它公共 自:类中,自己引用自己的理解(如,链表节点元素).静态看成动态,编译器的本质实现 内部类和普通类区别:内部类可priv

Java编程思想(十六) —— 联系JVM再谈Class

编程思想这个专栏停了好久了,主要是把精力放在了其他知识上,现在继续补上. 前面两篇写到RTTI和简单的反射介绍,先回顾一下: RTTI,运行时类型信息,多态的应用,类型转换其实是发生在运行期间. Class对象: 编程思想讲到的定义,Java使用Class对象来执行其RTTI,类是程序的一部分,每个类都有一个Class对象,其实每编写和编译一个新类,就会产生一个Class对象,其实这个对象时被保存在同名的.class文件中的.生成这个类对象,其实是JVM(Java虚拟机)使用了"类加载器&quo

《java编程思想》--多线程基础--Runnable

一.简单说下Runnable是什么 1.它是一个接口 2.只提供了run方法 3.这个接口提供了一个协议:实现这个接口的类是active的(不必成为Thread的子类) 1 /** 2 * The <code>Runnable</code> interface should be implemented by any 3 * class whose instances are intended to be executed by a thread. The 4 * class mu

java编程思想总结(二)

java编程思想总结(二) java编程思想总结是一个持续更新的系列,是本人对自己多年工作中使用到java的一个经验性总结,也是温故而知新吧,因为很多基础的东西过了这么多年,平时工作中用不到也会遗忘掉,所以看看书,上上网,查查资料,也算是记录下自己的笔记吧,过一段时间之后再来看看也是蛮不错的,也希望能帮助到正在学习的人们,本系列将要总结一下几点: 面向对象的编程思想 java的基本语法 一些有趣的框架解析 实战项目的整体思路 代码的优化以及性能调优的几种方案 整体项目的规划和视角 其它遗漏的东西

《Java编程思想(第4版)》pdf

下载地址:网盘下载 内容简介 编辑 本书赢得了全球程序员的广泛赞誉,即使是最晦涩的概念,在Bruce Eckel的文字亲和力和小而直接的编程示例面前也会化解于无形.从Java的基础语法到最高级特性(深入的面向对象概念.多线程.自动项目构建.单元测试和调试等),本书都能逐步指导你轻松掌握.[1] 从本书获得的各项大奖以及来自世界各地的读者评论中,不难看出这是一本经典之作.本书的作者拥有多年教学经验,对C.C++以及Java语言都有独到.深入的见解,以通俗易懂及小而直接的示例解释了一个个晦涩抽象的概

《Java编程思想》第一二章

前段时间一直通过网络教程学习Java基础,把面向对象部分学完之后本来打算继续深入学习,但是感觉自己操之过急了,基础根本不够扎实,所以入手了一本<Java编程思想>,希望先把基础打好,再深入学习. 不得不说这本书真的不是浪得虚名,对于我这样的新手看完一二章之后也觉得这本书值得买了.跟网上教程不同,这本书一开始便直接全面深入论述Java面向对象编程中对对象的理解,值得注意的是如果之前没有Java编程的基础,第一章看起来会比较吃力,而且效果也不太好,因为都是理论没有使用代码进行演示说明,所以作者也支

1.JAVA 编程思想——对象入门

对象入门 欢迎转载,转载请标明出处:    http://blog.csdn.net/notbaron/article/details/51040219 如果学JAVA,没有读透<JAVA 编程思想>这本书,实在不好意思和别人说自己学过JAVA.鉴于此,蛤蟆忙里偷闲,偷偷翻看这本传说中的牛书. 面向对象编程OOP具有多方面吸引力.实现了更快和更廉价的开发与维护过程.对分析与设计人员,建模处理变得更加简单,能生成清晰.已于维护的设计方案. 这些描述看上去非常吸引人的,不过蛤蟆还是没啥印象(至少到

JAVA编程思想学习笔记——第一章 对象导论

搞了一年多java,野路子出身,发现java基础这块还是相当的薄弱!故决定学习<Java编程思想>这本书.在此把学习的知识点记录下! 面向对象的五大特性 1.万物皆为对象 2.程序是对象的集合,它们通过发送消息来告诉彼此所要做的 3.每个对象都由自己的由其它对象所构成的存储 4.每个对象都拥有其类型 5.某一特定类型的所有对象都可以接收同样的信息  单根继承结构 所有的类都继承自单一的基类,Object.在单根集成结构中的所有对象都具有一个公用接口,所以他们归根到底都是相同的基本类型.单根集成

【java编程思想--学习笔记(四)】对象导论

写这篇博客的前言: 长话短说,我希望通过阅读<java编程思想>来使我的代码 简洁可用 . 目的的层次不同,首先具体的目标是,了解Java的特性和巩固Java的基础. 更抽象的目的如下: 1.期待以巩固基础的方式,使代码优美,简洁,高效. 2.使自己写的模块能够开放适度,好用. 3.形成一种对代码是否优美的审美观. 于是<Java编程思想>第一章 对象导论 由此开始. 1.1 抽象过程 java 相对于命令式语言的优势在于只针对于待解问题建模.后者所做的主要抽象要求所做问题基于计算

71.JAVA编程思想——JAVA与CGI

71.JAVA编程思想--JAVA与CGI Java 程序可向一个服务器发出一个CGI 请求,这与HTML 表单页没什么两样.而且和HTML 页一样,这个请求既可以设为GET(下载),亦可设为POST(上传).除此以外,Java 程序还可拦截CGI 程序的输出,所以不必依赖程序来格式化一个新页,也不必在出错的时候强迫用户从一个页回转到另一个页.事实上,程序的外观可以做得跟以前的版本别无二致. 代码也要简单一些,毕竟用CGI 也不是很难就能写出来(前提是真正地理解它).所以我们准备办个CGI 编程