首页 > 代码库 > think in java 读书笔记
think in java 读书笔记
java中没有单独函数的概念,依赖类的方法。
java中优化了向前引用,类可以在调用者之后。
java中包的命名方法实际上是网址的倒转。
c++中因为存在全局变量和函数所以会存在一个变量名冲突的问题,但是java中不存在全局变量,不同程序设计者通过不同的类将相同名字的变量和方法隔离。
static关键字
通常,我们创建类时会指出那个类的对象的外观与行为。除非用new 创建那个类的一个对象,否则实际上并
未得到任何东西。只有执行了new 后,才会正式生成数据存储空间,并可使用相应的方法。
但在两种特殊的情形下,上述方法并不堪用。一种情形是只想用一个存储区域来保存一个特定的数据——无
论要创建多少个对象,甚至根本不创建对象。另一种情形是我们需要一个特殊的方法,它没有与这个类的任
何对象关联。也就是说,即使没有创建对象,也需要一个能调用的方法。为满足这两方面的要求,可使用
static(静态)关键字。
需要注意的是:内存区域 一般被分为 4个部分 ,数据段,代码段,堆,栈,数据段也就是通常所说的的静态存储区域,所以呢,static 一般是存储在数据段的,另外堆是用来存储需要动态分配空间的变量,通俗的说就是new出来的。而栈呢就是存储我们通常所说的局部变量。但是java没有静态数据区,static数据是在堆里。
equals和==的区别
java中的数据类型,可分为两类:
1.基本数据类型,也称原始数据类型。byte,short,char,int,long,float,double,boolean
他们之间的比较,应用双等号(==),比较的是他们的值。
2.复合数据类型(类)
当他们用(==)进行比较的时候,比较的是他们在内存中的存放地址,所以,除非是同一个new出来的对象,他们的比较后的结果为true,否则比较后结果为false。 JAVA当中所有的类都是继承于Object这个基类的,在Object中的基类中定义了一个equals的方法,这个方法的初始行为是比较对象的内存地 址,但在一些类库当中这个方法被覆盖掉了,如String,Integer,Date在这些类当中equals有其自身的实现,而不再是比较类在堆内存中的存放地址了。
对于复合数据类型之间进行equals比较,在没有覆写equals方法的情况下,他们之间的比较还是基于他们在内存中的存放位置的地址值的,因为Object的equals方法也是用双等号(==)进行比较的,所以比较后的结果跟双等号(==)的结果相同。
具体参考:http://www.cnblogs.com/zhxhdean/archive/2011/03/25/1995431.html
finalize
java提供finalize()方法,垃圾回收器准备释放内存的时候,会先调用finalize()。
(1).对象不一定会被回收。
(2).垃圾回收不是析构函数。
(3).垃圾回收只与内存有关。
(4).垃圾回收和finalize()都是靠不住的,只要JVM还没有快到耗尽内存的地步,它是不会浪费时间进行垃圾回收的。
http://blog.csdn.net/carolzhang8406/article/details/6705831
初始化
初始化可以指定值,否则的话会有一个默认值。
对象的句柄没有引用实例前是null
初始化顺序
在一个类里,初始化的顺序是由变量在类内的定义顺序决定的。即使变量定义大量遍布于方法定义的中间,
那些变量仍会在调用任何方法之前得到初始化——甚至在构建器调用之前。初始化的顺序是首先static(如果它们尚未由前一次对象创建过程初始化),接着是非static 对象。
数组初始化:java中的数组初始化和c++中一样需要指定大小,但是这个大小是多少是可以在运行是确定的。
比如下面的代码在java中是合法的:
Random jj=new Random(); int ii=jj.nextInt(); ii=Math.abs(ii%500); Object [][]a=new Object[12][ii]; for(int i=0;i<12;i++) for(int j=0;j<ii;j++) { a[i][j]=new Double(10); }
java访问指示符
freindly
如果根本不指定访问指示符,就象本章之前的所有例子那样,这时会出现什么情况呢?默认的访问没有关键
字,但它通常称为“友好”(Friendly)访问。这意味着当前包内的其他所有类都能访问“友好的”成员,
但对包外的所有类来说,这些成员却是“私有”(Private)的,外界不得访问。由于一个编译单元(一个文
件)只能从属于单个包,所以单个编译单元内的所有类相互间都是自动“友好”的。因此,我们也说友好元
素拥有“包访问”权限。
public
使用public关键字时,它意味着紧随在public 后面的成员声明适用于所有人,特别是适用于使用库的客户
程序员,需要注意的是:
java程序是从一个public类的main函数开始执行的,(其实是main线程),就像C程序是从main()函数开始执行一样。只能有一个public类是为了给类装载器提供方便。一个public 类只能定义在以它的类名为文件名的文件中。class a 表示默认的访问级别,即只有包内的其他类能访问它(严格来说应该是 class A,类名一般大写)小应用程序只有一个类,一方面是因为定义的类越多,程序执行就越缓慢(需要多装载几个类)。
需要注意的是一个java文件中必须得有一个main()方法作为测试入口,如果不做测试只是作为一个组件的话可以没有main和public class。
private
private关键字意味着除非那个特定的类,而且从那个类的方法里,否则没有人能访问那个成员。同一个包
内的其他成员不能访问 private成员,这使其显得似乎将类与我们自己都隔离起来。
private的运用 单例模式:
package para;
public class singeltone
{public static void main(String args[]){ singel ssSingel=singel.makeSingel(); System.out.println(ssSingel); singel ssSingel2=singel.makeSingel(); System.out.println(ssSingel2); } }
class singel{ private singel(){ } static private singel s; public static singel makeSingel(){ if(s==null) s=new singel(); return s; } }
protected
有些时候,基础类的创
建者喜欢提供一个特殊的成员,并允许访问衍生类。这正是protected 的工作。它的意思是“它本身是私有的,但可由从这个类继
承的任何东西或者同一个包内的其他任何东西访问”。也就是说,Java 中的protected 会成为进入“友好”
状态。
java 中基本数据类型和对应的类
java中的基本数据类型是int float doubel long 等,与之对应的类有Integer Float等。他们是有区别的。
Integer是类,int是基本数据类型Integer是在堆中创建,int是创建在栈中
如果我们定义一个int类型的数,只是用来进行一些加减乘除的运算or作为参数进行传递,那么就可以直接声明为int基本数据类型,但如果要像对象一样来进行处理,那么就要用Integer来声明一个对象,因为java是面向对象的语言,因此当声明为对象时能够提供很多对象间转换的方式,与一些常用的方法。自认为java作为一们面向对象的语言,我们在声明一个变量时最好声明为对象格式,这样更有利于你对面向对象的理解。
final关键字
由于语境(应用环境)不同,final 关键字的含义可能会稍微产生一些差异。但它最一般的意思就是声明
“这个东西不能改变”。之所以要禁止改变,可能是考虑到两方面的因素:设计或效率。由于这两个原因颇
有些区别,所以也许会造成final 关键字的误用。
在接下去的小节里,我们将讨论final 关键字的三种应用场合:数据、方法以及类。
一
许多程序设计语言都有自己的办法告诉编译器某个数据是“常数”。常数主要应用于下述两个方面:
(1) 编译期常数,它永远不会改变
(2) 在运行期初始化的一个值,我们不希望它发生变化
对于编译期的常数,编译器(程序)可将常数值“封装”到需要的计算过程里。也就是说,计算可在编译期
间提前执行,从而节省运行时的一些开销。在 Java 中,这些形式的常数必须属于基本数据类型
(Primitives),而且要用 final关键字进行表达。
二
若随同对象句柄使用final,而不是基本数据类型,它的含义就稍微让人有点儿迷糊了。对于基本数据类
型,final 会将值变成一个常数;但对于对象句柄,final 会将句柄变成一个常数。
三
之所以要使用final 方法,可能是出于对两方面理由的考虑。第一个是为方法“上锁”,防止任何继承类改
变它的本来含义。设计程序时,若希望一个方法的行为在继承期间保持不变,而且不可被覆盖或改写,就可
以采取这种做法。
采用final 方法的第二个理由是程序执行的效率。将一个方法设成 final 后,编译器就可以把对那个方法的
所有调用都置入“嵌入”调用里。只要编译器发现一个final 方法调用,就会(根据它自己的判断)忽略为
执行方法调用机制而采取的常规代码插入方法(将自变量压入堆栈;跳至方法代码并执行它;跳回来;清除
堆栈自变量;最后对返回值进行处理)。相反,它会用方法主体内实际代码的一个副本来替换方法调用。这
样做可避免方法调用时的系统开销。当然,若方法体积太大,那么程序也会变得雍肿,可能受到到不到嵌入
代码所带来的任何性能提升。因为任何提升都被花在方法内部的时间抵消了。Java 编译器能自动侦测这些情
况,并颇为“明智”地决定是否嵌入一个final 方法。然而,最好还是不要完全相信编译器能正确地作出所
有判断。通常,只有在方法的代码量非常少,或者想明确禁止方法被覆盖的时候,才应考虑将一个方法设为
final。