java类的构成

java类的构成

  Java 技术具有卓越的通用性、高效性、平台移植性和安全性,广泛应用于PC、数据中心、游戏控制台、科学超级计算机、移动电话和互联网,同时拥有全球最大的开发者专业社群。以下是小编为大家搜索整理的java类的基本构成,希望能给大家带来帮助!

  1:Java 类的定义形式

  一个完整的 Java 类通常由下面六个部分组成:

  包定义语句

  import 语句

  类定义{

  成员变量

  构造方法

  成员方法

  }

  其中:只有类定义和“{}”是不可或缺的,其余部分都可以根据需要来定义。

  下面分别来学习各个部分的基本规则,看看如何写 Java 的类。

  2: 包

  2.1:包 是什么

  在 Java 中,包是类、接口或其它包的集合,包主要用来将类组织起来成为组,从而对类进行管理。

  2.2:包 能干什么

  包对于下列工作非常有用:

  (1):包允许您将包含类代码的文件组织起来,易于查找和使用适当的类。

  (2):包不止是包含类和接口,还能够包含其它包。形成层次的包空间。

  (3):它有助于避免命名冲突。当您使用很多类时,确保类和方法名称的唯一性是非常困难的。包能够形成层次命名空间,缩小了名称冲突的范围,易于管理名称。

  为便于管理数目众多的类,Java 语言中引入了“包”的概念,可以说是对定义的 Java类进行“分组” ,将多个功能相关的类定义到一个“包”中,以解决命名冲突、引用不方便、安全性等问题。

  就好似当今的户籍制度,每个公民除有自己的名字“张三” 、 “李四”外还被规定了他的户籍地。假定有两个人都叫张三,只称呼名字就无法区分他们,但如果事先登记他们的户籍分别在北京和上海,就可以很容易的用“北京的张三” 、 “上海的张三”将他们区分开来。如果北京市仍有多个张三,还可以细分为“北京市.海淀区的张三” 、 “北京市.西城区.平安大街的张三”等等,直到能惟一标识每个“张三”为止。

  JDK 中定义的类就采用了“包”机制进行层次式管理,下图显示了其组织结构的一部分:

  从图中可以看出,一个名为 java 的包中又包含了两个子包:io 包和 lang 包。lang 包中包含了 System, String, Object 三个类的定义。事实上,Java 包中既可以包含类的定义,也可以包含子包,或同时包含两者。

  简而言之: 从 逻辑 上 讲 , 包 是一 组 相 关类 的集 合 ; 从 物 理 上 讲 , 同 包即 同 目 录。

  2.1:JDK 中常 用的 包

  java.lang----包含一些 Java 语言的核心类,包含构成 Java 语言设计基础的类。在此包中定义的最重要的一个类是“Object” ,代表类层次的根,Java 是一个单根系统,最终的根就是“Object” ,这个类会在后面讲到。

  Java 并不具有“自由”的方法,例如,不属于任何类的方法,Java 中的所有方法必须始终属于某个类。经常需要使用数据类型转换方法。Java 在 Java.lang 包中定义了“包装对象”类,使我们能够实现数据类型转换。如 Boolean、Character、Integer、Long、Float 和Double,这些在后面会讲到。

  此包中的其它类包括:

  ? Math——封装最常用的数学方法,如正弦、余弦和平方根。

  ? String,StringBuffer——封装最常用的字符串操作。

  你不必显示导入该包,该 Java 包通常已经导入。

  java.awt----包含了构成抽象窗口工具集(abstract window toolkits)的多个类,这些类被用来构建和管理应用程序的图形用户界面(GUI)。

  javax.swing----完全 Java 版的图形用户界面(GUI)解决方案,提供了很多完备的组件,可以应对复杂的桌面系统构建。

  java.net----包含执行与网络相关的操作的类,如 URL, Socket, ServerSocket 等。

  java.io----包含能提供多种输入/输出功能的类。

  java.util----包含一些实用工具类,如定义系统特性、使用与日期日历相关的方法。还有重要的集合框架。

  2.2:Java 中 如何 表达 包 ——package 语 句

  Java 语言使用 package 语句来实现包的定义。package 语句必须作为 Java 源文件的第一条语句, 指明该文件中定义的类所在的包。 若缺省该语句, 则指定为无名包, 其语法格式为:

  package pkg1[.pkg2[.pkg3…]]; //“[]”表示可选Java 编译 器 把包对 应 于 文 件系 统 的目 录管 理,因此包也可以嵌套使用,即一个包中可以含有类的定义也可以含有子包,其嵌套层数没有限制。package 语句中,用‘.’来指明包的层次;

  Java 语言要求包声明的层次和实际保存类的字节码文件的目录结构存在对应关系, 以便将来使用该类时能通过包名(也就是目录名)查找到所需要的类文件。简单地说就是包的层次结构需要和文件夹的层次对应。

  注意:每 个源文 件 只 有一 个 包 的 声 明, 而 且包 名 应 该 全部 小 写 。

  具体来说,程序员要做以下工作:

  2.3:编译和 生 成 包

  如果在程序 Test.java 中已定义了包 p1,就必须将编译生成的字节码文件 Test.class 保存在与包名同名的子目录中,可以选用下述两种方式之一:

  采用下述命令编译:

  javac Test.java

  则编译器会在当前目录下生成 Test.class 文件, 再在适合位置手动创建一个名为 p1 的子目录,将 Test.class 复制到该 p1 目录下。

  采用简化的编译命令,就是可以带包编译

  javac -d destpath Test.java

  归入该包的类的字节代码文件应放在 java 的类库所在路径的 destpath 子目录下。 现在包的相对位置已经决定了,但 java 类库的路径还是不定的。事实上,java 可以有多个存放类库的目录,其中的缺省路径为 java 目录下的 lib 子目录,你可以通过使用-classpath 选项来确定你当前想选择的类库路径。 除此之外, 你还可以在 CLASSPATH 环境变量中设置类库路径。 destpath 为目标路径, 可以是本地的任何绝对或相对路径。 则编译器会自动在 destpath目录下建立一个子目录 p1,并将生成的.class 文件自动保存到 destpath/p1 下。例如:

  javac -d . Test.java

  javac -d C: est Test.java

  2.4:带包 运行

  运行带包的程序,需要使用类的全路径,也就是带包的路径,比如上面的那个程序,就使用如下的代码进行运行:

  java p1.Test

  3:import

  为了能够使用某一个包的成员,我们需要在 Java 程序中明确导入该包。使用“import”语句可完成此功能。在 java 源文件中 import 语句应位于 package 语句之后,所有类的定义之前,可以有 0~多条,其语法格式为:

  import package1[.package2…].(classname|*);

  java 运行时环境将到 CLASSPATH + package1.[package2…]路径下寻找并载入相应的字节码文件 classname.class。 “*”号为通配符,代表所有的类。也就是说 import 语句为编译器指明了寻找类的途径。

  例,使用 import 语句引入类程序:TestPackage.java

  java 编译器默认为所有的 java 程序引入了 JDK 的 java.lang 包中所有的类(import java.lang.*;) ,其中定义了一些常用类:System、String、Object、Math 等。因此我们可以直接使用这些类而不必显式引入。但使用其它非无名包中的类则必须先引入、后使用。

  3.1:Java 类 搜寻方 式

  程序中的 import 语句标明要引入 p1 包中的 Test 类, 假定环境变量 CLASSPATH 的值为

  “.;C:jdk6lib;D:ex” , java 运行环境将依次到下述可能的位置寻找并载入该字节码

  文件 Test.class:

  .p1Test.class

  C:jdk6libp1Test.class

  D:exp1Test.class

  其中, “.”代表当前路径,如果在第一个路径下就找到了所需的类文件,则停止搜索。

  否则依次搜索后续路径,如果在所有的路径中都未找到所需的类文件,则编译或运行出错。

  4: 访问修饰 符

  Java 语言允许对类中定义的各种属性和方法进行访问控制, 即规定不同的保护等级来限制对它们的使用。为什么要这样做?Java 语言引入类似访问控制机制的 目的 在 于实 现 信息的 封 装 和 隐藏。 Java 语言为对类中的属性和方法进行有效地访问控制, 将它们分为四个等级:private, 无修饰符, protected, public,具体规则如下:

  变量和方法可以处于四个访问级别中的一个:公共,受保护,无修饰符或私有。类可以在公共或无修饰级别。

  变量、方法或类有缺省(无修饰符)访问性,如果它没有显式受保护修饰符作为它的声明的一部分的话。这种访问性意味着,访问可以来自任何方法,当然这些方法只能在作为对象的同一个包中的成员类当中。

  以修饰符 protected 标记的变量或方法实际上比以缺省访问控制标记的更易访问。 一个protected 方法或变量可以从同一个包中的类当中的任何方法进行访问, 也可以是从任何子类中的任何方法进行访问。 当它适合于一个类的子类但不是不相关的类时, 就可以使用这种受保护访问来访问成员。

  5: 类定义

  Java 程序的基本单位是类,你建立类之后,就可用它来建立许多你需要的对象。Java把每一个可执行的成分都变成类。

  类的定义形式如下:

  这里,类名要是合法的标识符。在类定义的开始与结束处必须使用花括号。你也许想建立一个矩形类,那么可以用如下代码:

  6:构 造方 法

  6.1:什么是构造方法

  类有一个特殊的成员方法叫作构造方法, 它的作用是创建对象并初始化成员变量。 在创建对象时,会自动调用类的构造方法。

  6.2:构 造方 法定义规则

  Java 中的构造方法必须与该类具有相同的名字,并且没有方法的返回类型(包括没有void) 。另外,构造方法一般都应用 public 类型来说明,这样才能在程序任意的位置创建类的实例--对象。

  6.3:示 例

  下面是一个 Rectangle 类的构造方法,它带有两个参数,分别表示矩形的长和宽:

  6.4:说明

  每个类至少有一个构造方法。 如果不写一个构造方法, Java 编程语言将提供一个默认的,该构造方法没有参数,而且方法体为空。

  注意:如果一个类 中 已经 定义 了 构 造方 法则 系 统 不 再 提 供 默认 的 构 造方

  7:析构方法

  析构方法 finalize 的功能是: 当对象被从内存中删除时, 该成员方法将会被 自动调用。通常,在析构方法内,你可以填写用来回收对象内部的动态空间的代码。

  特别注意:当我们去调用析构方法的时候,并不会引起该对象实例从内存中删除,而是不会起到任何作用。

  在 Java 编程里面,一般不需要我们去写析构方法,这里只是了解一下就可以了。

  8:属性

  8.1:属性是什么

  简单点说,属性就是对象所具有的静态属性。

  8.2:定义规则

  Java 类中属性的声明采用如下格式:

  访问修饰符 修饰符 类型 属性名称=初始值;

  访问修饰符:可以使用四种不同的访问修饰符中的一种,包括 public(公共的)、protected(受保护的) ,无修饰符和 private(私有的) 。public 访问修饰符表示属性可以从任何其它代码调用。private 表示属性只可以由该类中的其它方法来调用。protected 将在以后的课程中讨论。

  修饰符:是对属性特性的描述,例如后面会学习到的:static、final 等等。

  类型:属性的数据类型,可以是任意的类型。

  属性名称:任何合法标识符

  初始值:赋值给属性的初始值。如果不设置,那么会自动进行初始化,基本类型使用缺省值,对象类型自动初始化为 null。

  8.3:说明

  属性有时候也被称为成员变量、实例变量、域,它们经常被互换使用。

  9:方 法

  9.1:方法是什么

  方法就是对象所具有的动态功能。

  9.2:定义规则

  Java 类中方法的声明采用以下格式:访问修饰符 修饰符 返回值类型 方法名称 (参数列表) throws 异常列表 {方法体}

  访问修饰符:可以使用四种不同的访问修饰符中的一种,包括 public(公共的)、protected(受保护的) ,无修饰符和 private(私有的) 。public 访问修饰符表示方法可以从任何其它代码调用。private 表示方法只可以由该类中的其它方法来调用。protected 将在以后的课程中讨论。

  修饰符:是对方法特性的描述,例如后面会学习到的:static、final、abstract、synchronized 等等。

  返回值类型::表示方法返回值的类型。 如果方法不返回任何值, 它必须声明为 void(空)。

  Java 技术对返回值是很严格的,例如,如果声明某方法返回一个 int 值,那么方法必须从所有可能的返回路径中返回一个 int 值(只能在等待返回该 int 值的上下文中被调用。 )

  方法名称:可以是任何合法标识符,并带有用已经使用的名称为基础的某些限制条件。

  参数列表:允许将参数值传递到方法中。列举的元素由逗号分开,而每一个元素包含一个类型和一个标识符。在下面的方法中只有一个形式参数,用 int 类型和标识符 days 来声明:public void test(int days){}

  throws 异常列表:子句导致一个运行时错误(异常)被报告到调用的方法中,以便以合适的方式处理它。异常在后面的课程中介绍。

  花括号内是方法体,即方法的具体语句序列。

  9.3:示例

  比如现在有一个“车”的类——Car, “车”具有一些基本的属性,比如四个轮子,一个方向盘,车的品牌等等。当然,车也具有自己的功能,也就是方法,比如车能够“开动”——run。要想车子能够开动,需要给车子添加汽油,也就是说,需要为 run 方法传递一些参数“油”进去。车子跑起来过后,我们需要知道当前车辆运行的速度,就需要 run 方法具有返回值“当前的速度” 。

  9.4:形参和实参

  形参:就是形式参数的意思。是在定义方法名的时候使用的参数,用来标识方法接收的参数类型,在调用该方法时传入。

  实参:就是实际参数的意思。是在调用方法时传递给该方法的实际参数。

  比如:上面的例子中“int oil”就是个形式参数,这里只是表示需要加入汽油,这个方法才能正常运行,但具体加入多少,要到真正使用的时候,也就是调用这个方法的时候才具体确定,加入调用的时候传入“80” ,这就是个实际参数。

  形参和实参有如下基本规则:

  (1):形参和实参的类型必须要一致,或者要符合隐含转换规则

  (2):形参类型不是引用类型时,在调用该方法时,是按值传递的'。在该方法运行时,形参和实参是不同的变量,它们在内存中位于不同的位置,形参将实参的值复制一份,在该方法运行结束的时候形参被释放,而实参内容不会改变。

  (3):形参类型是引用类型时,在调用该方法时,是按引用传递的。运行时,传给方法的是实参的地址, 在方法体内部使用的也是实参的地址, 即使用的就是实参本身对应的内存空间。所以在函数体内部可以改变实参的值。

  9.5:参数可变的方法

  从 JDK5.0 开始,提供了参数可变的方法。

  当不能确定一个方法的入口参数的个数时,5.0 以前版本的 Java 中,通常的做法是将多个参数放在一个数组或者对象集合中作为参数来传递,5.0 版本以前的写法是:

  int sum(Integer[] numbers){…}

  //在别处调用该方法

  sum(new Integer[] {12,13,20});

  而在 5.0 版本中可以写为:

  int sum(Integer... numbers){//方法内的操作}

  注意:方法定义中是三个点

  //在别处调用该方法

  sum(12,13,20);//正确

  sum(10,11); //正确

  也就是说,传入参数的个数并不确定。但请注意:传入参数的类型必须是一致的,究其本质,就是一个数组。

  显然,JDK5.0 版本的写法更为简易,也更为直观,尤其是方法的调用语句,不仅简化很多,而且更符合通常的思维方式,更易于理解。

  Java类基本构成

  1、包:(package)类名管理空间,由于Java编译器为每个类生成字节码文件,且文件名与类名相同,因此同名的类可能发生冲突,所以引入了包的概念。

  A:包提供了一种命名机制和可见性限制机制;在java中将功能相似类用一个包来进行管理

  B:定义一个包package定义,若要定义包,则类的第一行必须无空格,业务注释;如:package+包名。包名通常都由小写字母组成。

  2、引入:(import)import语句在功能上与C/C++语言中的include语句相同

  A:两者之间的不同点:

  a、Include是包含外部文件,import是输入外部类,

  b、import末尾必须以“;”结尾。

  B:import语句必须放在package之后,若没有package,则该语句放在类文件名的开头;

  C:若要引入某一个类,必须写完整的包名和类名;如:importpackage.classname

  3、类:(class)类是java程序的基本单位,类的实例是对象。

  A:若在源程序中包含有公共类的定义,则该源文件名必须与公共类的名字完全一致,否则编译时就会报错。

  B:在一个java源程序中至多只能有一个公共类的定义。

  C:若在一个源程序中有多个类定义,则在编译时将为每个类生成一个.class文件

  4、变量:(variable)一个类中通常都包含数据和函数两种类型的元素,一般把它们称为变量和成员函数;也把成员函数成为方法。

  将数据和代码通过类结合在一起,就行成了封装的概念。

  变量也叫做域,它是用于定义属性类的数据,这些数据是用来描述对象的状态,方法就是对这个数据进行操作。

  5、方法:(method)指引类进行具体的活动和操作

  6、注释:java注释分为三种

  A:单行注释:用//表示

  B:多行注释:用/*.................................................*/表示

  C:文档注释:用/**.................................................*/表示

  java类文件内容介绍

  一、什么是Java类文件

  Java类文件是Java程序的二进制表示形式。每一个类文件代表一个类或者接口。不可能在一个类文件中放入多个类或者接口。这样就使得无论类文件是在哪一种平台上生成,都可以在任何主机上执行。

  虽然类文件是Java体系结构的一部分,但是他并不是与Java语言不可分的。你可以将其他语言的程序编译为类文件,也可以将Java程序文件编译为其他二进制形式。

  Java类文件是一个基于8-bit字节的二进制流。数据块顺序的、无分割符的、big-endian的形式存储。

  二、类文件的内容

  Java的类文件中包含了所有Java虚拟机所需要的关于类和接口的信息。所有类文件中的信息都以以下的四种基本类型的存储:

  Table 6-1. Class file "primitive types"

  u1 a single unsigned byte

  u2 two unsigned bytes

  u4 four unsigned bytes

  u8 eight unsigned bytes

  1、魔术编码(magic)

  每一个Java类文件的开头四个字节都是魔术编码(OxCAFEBABE)。通过魔术编码可以很容易识别类文件。

  2、副版本号和主版本号(minor version and major version)

  剩下的四个字节是副版本号和主版本号。但Java技术在进化时,一些新的特性可能会被加入到类文件中。每一次类文件格式的变化,都会相应的改变版本号。虚 拟机通过版本号来识别自己能够处理的类文件。Java虚拟机往往只能处理一个给定的主版本号和其下的一些副版本号。虚拟机必须拒绝那些不再处理范围内的类 文件。

  Java类和对象的概念

  Java是一门面向对象的编程语言,理解Java,首先要理解类与对象这两个概念。

  Java中的类可以看做C语言中结构体的升级版。结构体是一种构造数据类型,可以包含不同的成员(变量),每个成员的数据类型可以不一样;可以通过结构体来定义结构体变量,每个变量拥有相同的性质。例如:

  #includeint main(){// 定义结构体 Studentstruct Student{// 结构体包含的变量char *name;int age;float score;};// 通过结构体来定义变量struct Student stu1;// 操作结构体的成员stu1.name = "小明";stu1.age = 15;stu1.score = 92.5;printf("%s的年龄是 %d,成绩是 %f ", stu1.name, stu1.age, stu1.score);return 0;}

  运行结果:

  小明的年龄是 15,成绩是 92.500000

  Java中的类也是一种构造数据类型,但是进行了一些扩展,类的成员不但可以是变量,还可以是函数;通过类定义出来的变量也有特定的称呼,叫做“对象”。例如:

  public class Demo {public static void main(String[] args){// 定义类Studentclass Student{ // 通过class关键字类定义类// 类包含的变量String name;int age;float score;// 类包含的函数void say(){System.out.println( name + "的年龄是 " + age + ",成绩是 " + score );}}// 通过类来定义变量,即创建对象Student stu1 = new Student(); // 必须使用new关键字// 操作类的成员stu1.name = "小明";stu1.age = 15;stu1.score = 92.5f;stu1.say();}}

  运行结果:

  小明的年龄是 15,成绩是 92.5

  在C语言中,通过结构体名称就可以完成结构体变量的定义,并分配内存空间;但是在Java中,仅仅通过类来定义变量不会分配内存空间,必须使用new关键字来完成内存空间的分配。

  可以将类比喻成图纸,对象比喻成零件,图纸说明了零件的参数及其承担的任务;一张图纸可以生产出具有相同性质的零件,不同图纸可以生产不同类型的零件。

  在Java中,使用new关键字,就可以通过类来创建对象,即将图纸生产成零件,这个过程叫做类的实例化,因此也称对象是类的一个实例。

  注意:类只是一张图纸,起到说明的作用,不占用内存空间;对象才是具体的零件,要有地方来存放,才会占用内存空间。

  类所包含的变量和函数都有特定的称呼,变量被称为属性(通常也称成员变量),函数被称为方法,属性和方法统称为类的成员。

  面向对象编程(Object Oriented Programming, OOP)

  类是一个通用的概念,Java、C++、C#、PHP等很多编程语言中都有类,都可以通过类创建对象。可以将类看做是结构体的升级版,C语言的晚辈们看到了C语言的不足,尝试加以改善,继承了结构体的思想,并进行了升级,让程序员在开发或扩展大中型项目时更加容易。

  因为Java、C++等语言都支持类和对象,所以使用这些语言编写程序也被称为面向对象编程,这些语言也被称为面向对象的编程语言。C语言因为不支持类和对象的概念,被称为面向过程的编程语言。

  实际上,面向对象只是面向过程的升级。

  在C语言中,可以将完成某个功能的重复使用的代码块定义为函数,将具有一类功能的函数声明在一个头文件中,不同类型的函数声明在不同的头文件,以便对函数进行更好的管理,方便编写和调用。

  在Java中,可以将完成某个功能的代码块定义为方法,将具有相似功能的方法定义在一个类中,也就是定义在一个源文件中(因为一个源文件只能包含一个公共的类),多个源文件可以位于一个文件夹,这个文件夹有特定的称呼,叫做包。

  图1 C语言中项目的组织结构

  图2 Java中项目的组织结构

  面向对象编程在软件执行效率上绝对没有任何优势,它的主要目的是方便程序员组织和管理代码,快速梳理编程思路,带来编程思想上的革新。

  Java类和对象的初始化顺序

  类装载步骤

  在Java中,类装载器把一个类装入Java虚拟机中,要经过三个步骤来完成:装载、链接和初始化,其中链接又可以分成校验、准备和解析三步,除了解析外,其它步骤是严格按照顺序完成的,各个步骤的主要工作如下:

  装载:查找和导入类或接口的二进制数据;

  链接:执行下面的校验、准备和解析步骤,其中解析步骤是可以选择的;

  校验:检查导入类或接口的二进制数据的正确性;

  准备:给类的静态变量分配并初始化存储空间;

  解析:将符号引用转成直接引用;

  初始化:激活类的静态变量的初始化Java代码和静态Java代码块。

  其中 初始化(initialization)包含两部分:

  1.类的初始化(initialization class & interface)

  2.对象的创建(creation of new class instances)。

  因为类的初始化其实是类加载(loading of classes)的最后一步,所以很多书中把它归结为“对象的创建”的第一步。其实只是看问题的角度不同而已。为了更清楚的理解,这里还是分开来。

  顺序:

  因为类的加载肯定是第一步的,所以类的初始化在前。大体的初始化顺序是:

  类初始化 -> 子类构造函数 -> 父类构造函数 -> 实例化成员变量 -> 继续执行子类构造函数的语句

  下面结合例子,具体解释一下。

  1. 类的初始化(Initialization classes and interfaces)

  其实很简单,具体来说有:

  (a)初始化类(initialization of class),是指初始化static field 和执行static初始化块。

  public class Demo{ //初始化static field, //其中= "initialization static field"又叫做static field initializer private static String str = "initialization static field"; //初始化块,又叫做static initializer,或 static initialization block static { System.out.println("This is static initializer"); } }

  btw,有些书上提到static initializer 和 static field initializer 的概念,与之对应的还有 instance initializer 和 instance variable initializer。例子中的注释已经解释了其含义。

  (b)初始化接口(initialization of interface),是指初始化定义在该interface中的field。

  *注意*

  1. initialization classes 时,该class的superclass 将首先被初始化,但其实现的interface则不会。

  initialization classes 时,该class的superclass,以及superlcass的superclass 会首先被递归地初始化,一直到java.lang.Object为止。但initialiazation interface的时候,却不需如此,只会初始化该interface本身。

  2. 对于由引用类变量(class field)所引发的初始化,只会初始化真正定义该field的class。

  3. 如果一个static field是编译时常量(compile-time constant),则对它的引用不会引起定义它的类的初始化。

  为了帮助理解最后两点,请试试看下面的例子:

  Initialization类

  public class Initialization { static { System.out.println("Initialization Main class"); } public static void main(String[] args) { System.out.println(Sub.y); System.out.println(Sub.x); System.out.println(Sub.z); } }

  Sub类

  public class Sub extends Super { public static final int y = 2005; public static int z; static { System.out.println("Initialization Sub"); } }

  Super类

  public class Super { public static int x = 2006; static { System.out.println("Initialization Super"); } }

  输入结果

  Initialization Main class

  2005

  Initialization Super

  2006

  Initialization Sub

  从这个结果可以看到,

  static块在类中会先执行;(实际上是先加载static成员变量,然后是static代码块)

  static 的final变量不会引起类的初始化;

  子类Sub引用父类Super里面的变量,就会引起父类的初始化,但不会引起子类的初始化;

  static的成员变量也有默认值。

  2. 对象的创建(creation of new class instances)

  看例子来说明:

  InitializationOrder类

  public class InitializationOrder { public static void main(String[] args) { SubClass sb = new SubClass(); } }

  SuperClass类

  public class SuperClass{ static { System.out.println("SuperClass static"); } SuperClass(String str){ System.out.println(str); } }

  Interface类

  interface Interface{ static SuperClass su = new SuperClass("Interface new SuperClass"); }

  SubClass类

  public class SubClass extends SuperClass implements Interface{ static { System.out.println("SubClass static"); } private SuperClass su = new SuperClass("initialization variable"); SubClass() { super("super"); new SuperClass("new SuperClass"); } }

  输出结果

  SuperClass static

  SubClass static

  super

  initialization variable

  new SuperClass

  解释一下:

  1) Java虚拟机要执行InitializationOrder类中的static 方法main(),这引起了类的初始化。开始初始化InitializationOrder类。具体的步骤略去不说。

  2) InitializationOrder类初始化完毕后,开始执行main()方法。语句SubClass sb = new SubClass()将创建一个SubClass对象。加载类SubClass后对其进行类初始化,因为Subclass有一个父类SuperClass,所以先初始化SuperClass类。于是看到输出“SuperClass static”。

  3) SuperClass类初始化完毕后,开始初始化SubClass类,输出“SubClass static”。

  4) 至此,类的加载工作全部完成。开始进入创建SubClass的对象过程。先为SubClass类和其父类SuperClass类分配内存空间,这时Super su 被赋值为null。

  5) 执行构造函数SubClass(),执行super(), 调用父类的构造函数,输出“super”。

  6) 初始化SubClass类的成员变量su,输出“initialization variable”。

  7) 继续执行构造函数的剩余部分,执行new SuperClass("new SuperClass"),输出“new SuperClass”,这时Super su 被赋值新建对象的引用。

  8) 而SubClass虽然实现了接口Interface,但是初始化它的时候并不会引起接口的初始化,所以接口Interface中的static SuperClass su = new SuperClass("Interface new SuperClass")自始至终都没有被执行到。

  所以对象的创建,具体步骤如下:

  (1) 所有的成员变量—包括该类,及它的父类中的成员变量--被分配内存空间,并赋予默认值。(这里是第一次初始化成员变量)

  (2) 为所调用的构造函数初始化其参数变量。(如果有参数)

  (3) 如果在构造函数中用this 调用了同类中的其他构造函数,则按照步骤(2)~(6)去处理被调用到的构造函数。

  (4) 如果在构造函数中用super调用了其父类的构造函数,则按照步骤(2)~(6)去处理被调用到的父类构造函数。

  (5) 按照书写顺序,执行instance initializer 和 instance variable initializer来初始化成员变量。(这里是第二次初始化成员变量)

  (6) 按照书写顺序,执行构造函数的其余部分。

  总结:

  从类的初始化和对象的创建步骤,可以知道,一个类是先初始化static的变量和static句块,然后在分配该类以及父类的成员变量的内存空间,赋予默认值,然后开始调用构造函数。而子类和父类之间,则先初始化和创建父类,然后在初始化和创建子类的。

  java system类使用方法示例

  常用的方法:

  复制代码 代码如下:

  long currentTimeMillis(); 获取当前时间的毫秒值

  void exit();终止当前正在运行的 Java 虚拟机。

  复制代码 代码如下:

  public static void Method(){

  long l = System.currentTimeMillis();

  System.out.println(l);

  System.exit();

  }

  描述系统属性信息:Properties System.getProperties();

  该方法获取的信息存储在Properties集合中

  因为Properties是Hashtable的子类,也就是Map集合的一个子类对象,要倒入util包

  那么可以通过map的方法取出该集合中的元素

  该集合中的键和值存储的都是字符串,没有泛型的定义

  复制代码 代码如下:

  public static void Method Properties(){

  //获取当前系统所有属性信息

  Properties prop = System.getProperties();

  //遍历prop中的属性信息,也可以使用迭代器

  for(Object obj : prop.keySet()){

  String value = (String)prop.get(obj);

  System.out.println(obj+"==="+value);

  //通过键获取对应的属性信息

  String value = System.getProperty("os.name");//如果没有该键返回null

  System.out.println(value);

  }

  }

  在系统中自定义系统信息

  复制代码 代码如下:

  public static void SetProperties(){

  System.setProperty("makey","myvalue");

  System.out.println(System.getProperty("makey"));

  }

  out:标准输出,默认是显示器

  in:标准输入,默认是键盘

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 yyfangchan@163.com (举报时请带上具体的网址) 举报,一经查实,本站将立刻删除