Java读书笔记05 类与对象

  

  本文为java中对象与类等的基本知识,包括方法、构造、析构、静态域、初始化、包、路径等。

对象与对象变量

  在Java中,任何对象变量的值都是对存储在另外一处的一个对象的引用。new操作符的返回值也是一个引用。

  可以把Java中的数据类型分为两类,一类是基本数据类型,即前面提到的8种基本数据类型(4种整型,2种实数,1种字符,1种布尔);另一类是引用类型(reference type)。

   

  下列语句:

  Date deadline = new Date();

  有两个部分。表达式new Date()构造了一个Date类型的对象,并且它的值是对新创建对象的引用,这个引用被存储在变量deadline中。

  可以显示地将对象变量设置为空(null)

  应该将Java的对象变量看作是C++的对象指针。

  引用类型是用在对象上的,一个对象可以被多个引用所指向,但同一时刻,每个引用只能指向唯一的一个对象。如果一个对象被多个引用所指向,那么无论哪个引用对对象属性进行了修改,都会反映到其他的引用当中。

  C++中没有空引用,并且引用不能被赋值。

  所有的Java对象都存储在堆中。变量包含的是指向堆对象的指针。引用存放的是对象的地址

  在Java中使用clone方法来获得对象的完整拷贝。

 

用户自定义类

  在一个源文件中,只能有一个公有类,但可以有任意数目的非公有类。

  源文件名必须与公有类的名字相匹配。

  当编译源程序时所有使用到的类都会被编译。

 

方法

  Java中所有的方法都必须在类的内部定义,但并不像C++那样把类内部定义的方法作为inline,是否将某个方法作为内联方法是Java虚拟机的任务。

  若需要返回一个可变数据域的拷贝,就应该使用clone。

 

构造器

  构造器即构造函数,工作方式与C++基本相同。但是所有的Java对象都是在堆中构造的,构造器总是伴随着new操作符一起使用。

  如果在编写一个类时没有编写构造器,系统就会提供一个默认构造器(默认构造器是指没有参数的构造器)。系统提供的这个默认构造器会将所有的实例域设置为默认值。

  如果类中至少提供了一个构造器,但是没有提供默认的构造器,那么在构造对象时若不提供构造参数就视为不合法。用户如果希望不提供参数时,所有域拥有默认的值,可以提供一个空的默认构造器。

  如果构造器的第一个语句形如this(…),那么这个构造器将调用同一个类的另一个构造器。

  注意:在C++中一个构造器不能调用另一个构造器,必须将抽取出的公共初始化代码编写成一个独立的方法。

 

方法参数

 

隐式参数与显式参数

  每一个方法中,this表示隐式参数,表示对象。

  显式参数是列在方法括号中的数值。

 

方法参数的传递

  C++有值调用和引用调用,引用参数标有&符号。

  Java程序设计语言使用值调用,方法得到的是参数值的一个拷贝。

  即对于Java中的方法参数传递,无论传递的是原生数据类型,还是引用类型,统一是传值(pass by value)。

  对于基本数据类型来说,方法中的变量被初始化为实参的一个拷贝,方法结束后,原来的在方法外部的变量并不改变,而方法中的变量不再使用。

  对于对象引用来说,方法中的变量被初始化为对象引用值的拷贝,即一个对象的引用。方法可以改变一个对象参数的状态。

  但是认为Java对对象采用的是引用调用,这种理解是不对的。如果将两个对象的引用的拷贝在方法中交换,这样并不能够真的交换这两个对象。这说明一个方法不能让对象参数引用一个新的对象。

 

静态域与静态方法

 

静态域:

  如果将域定义为static,那么每个类中只有一个这样的域。而每一个对象对于所有的实例域却都有一份自己的拷贝。

 

静态常量:

  public static final double PI=3.1415926535;

  public static final PrintStream out=…;

 

静态方法:

  静态方法是不能向对象实施操作的方法。即没有隐式的参数this。

  main方法是一个静态方法,因为在启动程序的时候还没有任何一个对象。

  (每个类可以有个main方法,这是对类进行单元测试时一个常用技巧。)

  因为静态方法不能操作对象,所以不能在静态方法中访问实例域。但是静态方法可以访问自身类中的静态域。

  以下两种情况使用静态方法:

    1.当一个方法不需要访问对象状态,所有参数都是通过显示参数提供的。

    2.当一个方法只需要访问类的静态域。

 

显式域初始化

  在执行构造器之前先进行赋值,当一个类的所有构造器都希望将相同的值赋予某个特定的实例域时,这种方法特别有用。

  初始值不一定是常量,域可以调用方法来进行初始化。

 

静态初始化:

  对静态域进行初始化可以将代码放在一个块中,并标记关键字static。在类第一次加载的时候,将会进行静态域的初始化,与实例域一样,静态域的默认初始值为false或null,除非将它们显式设置成其他值。

  所有的静态初始化语句以及静态初始化块  都将按照类定义中出现的顺序执行。

 

对象析构与finalize方法

  Java有自动的垃圾回收器,不需要人工回收内存,所以不支持析构器。

  当使用了内存之外的其他资源,如文件或使用了系统资源的另一个对象的句柄,在这种情况下,当资源不再需要的时候,将其回收和再利用十分重要。

  可以为任何一个类添加finalize方法,该方法将在垃圾回收器清除对象之前被调用。在实际应用中,不要使用finalize方法回收任何短缺的资源,这是因为很难知道这个方法什么时候才能够被调用。

  如果某个资源需要在使用完毕后立刻被关闭,就需要人工管理。提供一个类似dispose或close这样的方法,用来做相应的清理。如果一个类使用了这样的方法,当对象不再使用时一定要调用它。

 

  package将类组织起来。

  所有标准的Java包都处于java和javax包层次中。

  使用包的主要原因是确保类名的唯一性,Sun公司建议将公司的英特网域名以逆序的形式作为包名,并且对于不同的项目使用不同的子包。

  包嵌套的唯一目的是管理唯一的名字。从编译器的角度来看,嵌套的包之间没有任何关系。每一个都拥有独立的类集合。

 

类的导入

  一个类可以使用所属包中的所有类,以及其他包中的公有类。

  访问另一个包中的共有类有两种方式:

  1.在每个类名之前添加完整的包名。如:

  java.util.Date today = new java.util.Date();

  2.使用import语句(位于源文件顶部,package语句的后面)导入一个特定的类或者整个包。如:

  import java.util.*;

  还可以导入一个包中的特定类:

  import java.util.Date;

 

静态导入

  import语句不仅可以导入类,还增加了导入静态方法和静态域的功能。

  import static java.lang.System.*;

 

将类放入包中

  要想将一个类放入包中,就必须将包的名字放在源文件的开头。如:

  package com.horstmann.corejava;

  如果没有在源文件中放置package语句,那么这个源文件中的类就被放置在一个默认包中,默认包是一个没有名字的包。

 

虚拟机如何定位类

  类存储在文件系统的子目录中,类的路径必须与包名匹配。

  另外,还可以利用JAR实用程序将类文件添加到归档文件中。在一个归档文件中,可以包含多个类文件和子目录,这样既可以节省又可以改善性能。

  类路径所列出的目录和归档文件是搜寻类的起始点,是所有基目录的集合,基目录中的子目录可以用于包含类文件。

  设置类路径的方法取决于编译环境。如果使用JDK,那么就有两种选择:为编译器和字节码解释器指定-classpath选项,或者设置CLASSPATH环境变量。

  具体的设置细节取决于操作系统。

  句点.表示当前目录,Windows环境中,各基目录以分号;间隔。

  由于运行时库文件(在jre/lib与jre/lib/ext目录下的rt.jar和一些其他的JAR文件)会被自动地搜索,所以不必将它们显式地列在类路径中。

  为编译器设置类路径:

  javac –classpath …

  也可以用-cp代替-classpath

  javac编译器总是在当前目录中查找文件,而java解释器仅在类路径中有.目录的时候,才查看当前目录。

 

包作用域

  标记为public的部分可以被任意的类使用;

  标记为private的部分只能被定义它们的类使用。

  如果没有指定public或private,那么这个部分可以被同一个包中的所有方法访问。

posted @ 2012-08-16 09:49  圣骑士wind  阅读(1696)  评论(1编辑  收藏  举报