ganbin@tarena.com.cn 《Core Java 课件》 Day 01 一、 从面向过程编程到面向对象编程的思维转变 我们知道所有的计算机程序都是由两类元素组成:代码和 数据。此外从概念上将讲,程序还可以以他的代码或是数据为 核心进行组织编写。也就是说一些程序围绕“正在发生什么编 写“,而另一些程序则围绕”谁将被影响“编写。这两种范型 决定程序的构建方法。第一种方法被称为面向过程的模型,用 他编写的程序都具有线性执行的特点。面向过程的模型可以认 为是代码作用于数据,用 C 写的程序就是典型的面向过程模型。 第二种方法也就是我们现在正在学习的面向对象编程,面向对 象编程围绕她的数据(即对象)和为这个数据严格定义的接口 来组织程序。面向对象的程序实际上就是用数据控制对代码的 访问。CoreJava 就是一门纯面向对象编程的语言。 学习方法很简单,就是模仿、改进、创新,循环往复。 二、 什么是字节码和虚拟机: 字节码是一套设计用来在 Java 运行时系统下执行的高度优化的 指令集。该 Java 运行时系统称为 Java 虚拟机(JVM)。JVM 其实 就是一个字节码解释器。虚拟机将字节码解释成机器码给 CPU 执行,所以我们在 java 中通过虚拟机的这种解释执行方式来屏 蔽底层操作系统的差异。 JRE = JVM+编译器 - 1 - ganbin@tarena.com.cn JDK= JVM+编译器+类库 查看类库源码在:JDK/src.zip 压缩包里 三、 环境变量的设置: 需要新加的两个环境变量 1、J AVA_ HOM E:指名 JDK 的位置。 2、CLASSPATH:指名到哪里去找运行时需要用到的类代码(字 节码) 原有的环境变量 1、 PATH:指名可执行程序的位置。 2、 EXPORT :将指定的环境变量声明为全局的。 我们在.bash_profile 下的环境变量设置。 JAVA_HOME=/opt/jdk1.5 CLASSPATH=. PATH=$PATH:$JAVA_HOME/bin:. 注: “.”代表当前目录 当我们把环境变量都配置好了以后在终端敲入”java -version”命令如果出现 JDK 版本号信息就表示我们环 境变量设置成功了。 Bin 目录下放的是一些 JDK 命令 四、 kate 工具的使用 - 2 - ganbin@tarena.com.cn 这个就不多做描述了,大家多试试就清楚了 五、 我们的第一个 Java 程序 public class MyFirstJava{ public static void main(String[] args){ System.out.println(“Hello World”); } } 注: 1、我们要求类名必须和文件名一致,只不过文件名多了个.java 的后坠。 2、main 函数是我们整个程序的执行入口所以必须是静态公开 的。 编译:javac MyFirstJava.java 编译后我们可以看到目录下多了一个 MyFirstJava.class 文件。这就是 Java 编译原文件后生成的字节码文件。 执行:java MyFirstJava 将字节码文件交给 JVM 去解释执行。 思考: 1、为什么编译后不生成可执行文件(注:所有的可执 行文件都是机器代码) 2、Java 的跨平台特性(SUM 口号 :一次编译到处运行); - 3 - ganbin@tarena.com.cn 六、 包结构 为了根据需要将不同的原文件放在不同的目录下我们引入了 包。包我们可以看作就是一个存放 java 原文件的目录。 在源码的基础上声明一个包名:package sd0604 加包后我们用“javac –d . MyFirstJava.java”编译后生成的 字节码文件就会放在我们指定的包(目录)结构下. 如果我们想指定多级目录那么在目录明之间我们可以用.作 为分隔符。 例如:package sd0604.najing.xuanwu 七、 CoreJava 中的注释 1、//单行注释 2、/* */多行注释 3、/** */文档注释 文档注释可以由 java doc 命令单独提取出来生成注释文档。 例:javadoc MyFirstJava.java 我们在生成的注释文件中可以打开 index 入口页面来查看我们 刚刚生成的注释文档。 文档注释一般写在类、方法、属性定义之前 前两种注释和 C++相同。 注意:1、我们可以用 javadoc –help 命令来查看该命令的其他 - 4 - ganbin@tarena.com.cn 用法。 2、同样我们可以用“javadoc –d 路径名 *.java”来指 定生成文档注释的位置。 3、可以在文档注释中加入 HTML 标签来控制生成注释 文档的显示格式。 八、 jar 命令的用法 我们可以用“jar –cvf m n”命令来将文件打包成 jar 压缩包。 m: 要生成 jar 包的名字 n: 要压缩文件的文件名(可以是多个文件或一个目录) 生成的 jar 文件实际上就是一个普通的 zip 压缩文件 顺便说一下解包的命令:unzip *.jar 九、计算机运行一个 java 程序的过程 1、 启动 JVM 2、 通过 JAVA_HOME\jre\lib 目录下找到对应的类 3、 如果的2不找不到则在环境变量中配置的CLASSPATH配置 的路径中找类,这就是为什么我们要在 CLASSPATH 中配上 当前路径的原因。 十、import 声明的作用 当我们要用一个JDK定义好的类时我们需要在Java程序中配上该 - 5 - ganbin@tarena.com.cn 类对应的 jar 包。(类似于 C++中了#include 预处理指令) 例:import java.util.*; 这里大家注意一点:由于 java.lang.*包中的类是我们编程中经常要 使用的,所以这个包下的类我们不用特别用 import 在程序中声明。 但当我们要用到其他包中的类似我们就必须用 import 声明了。 awt:抽象窗口工具. 如果大家想了解什么包做什么用的话大家课以看看我给大家的 API 文档,上面有对所有这些包用法的解释。 十一、java 中的垃圾回收器 因为有了垃圾回收器,我们可以不用顾虑对象创建后占用系统资 源的问题。我们只用负责对象的创建,而对象销毁和资源释放的问题 就可以留给垃圾回收器做了。这里我们需要注意的是垃圾回收器一般 只会在内存空间不够的情况下进行资源回收。 十二、java 中标识符的命名规则 1、 只能以字母、下划线或”$”开头,严格区分大小写,且长度 不限。 2、 类名的每个单词的首字母大写 3、 方法名属性名的第一个单词小写,以后的每个单词首字母大 写 4、 所有的包结构名字都是小写 - 6 - ganbin@tarena.com.cn 5、 常量名所有字母大写 注:第一点是必须遵守的,2~5 点不遵守也不会出错,但建议大 家严格遵守以上命名规范。 十三、java 中的关键字和保留字 查书 十四、java 中的八中基本数据类型 1. boolean:占 1 个字节 2. byte :占 1 个字节 3. char : 占 2 个字节(可以用来保存汉字) 4. short :占 2 个字节 5. int :占 4 个字节 6. long : 占 8 个字节 7. float : 占 4 个字节 8. double : 占 8 个字节 十五、正负数在内存空间中的存放 正数在内存空间中存发的是源码。 负数在内存空间中存发的是正数源码对应的补码。 补码:在源码的基础上取反后末位加 1。 - 7 - ganbin@tarena.com.cn 十六、基本数据类型之间的转换 1、 正向过程:从低字节到高字节可以自动转换。 byte->short->int->long->float->double 注:boolean 不能转。 2、 逆向过程:从高字节到低字节用强制类型转换 例:int a = (int)3.12 注:逆向转换将丢失精度。 十七、java 中的转义字符 1. 表示格式控制的转义字符(如:\n \t)与 C++相同。 2. Java 中用“\u 四位十六进制的数字”表是将字符转换成对应 的 unicode 编码。 十八、表达式和流程控制 instanceof():用户判断某一个对象是否属于某一个类的实例。 运算符:单目运算符、双目运算符、位运算符 注:1、>>>是 corejava 中的位移运算符,表示右移,左边空出 的位以 0 添充。>>右移 2、将一个数右移 n 位相当于将该数除以 2 的 n 次方; 3、 将一个数左移 n 位相当于将该数乘以 2 的 n 次方; 4、 &&、||是短路运算符(左边条件不符合时不会执行右边的判 断) - 8 - ganbin@tarena.com.cn Day02 一、流程控制语句 1、两路分支选择 If else 配对原则:else 一定会和离他最近的且没有与别的 else 配 对的 if 配对; 2、多路分支选择 switch (byte,short,int,char){ case xxx: break; case xxx: break; default: } 3、循环结构 3.1 for(初始化;条件;调整){语句块} 该结构在知道循环次 数的时候使用 初始化语句只执行一次; 判断条件Æ执行语句块Æ执行调整Æ判断条件 for(;;)表示为无限循环 注:for 循环中两个分号是不能省略的。 3.2 While(条件){语句块}改结构在不知道循环次数的时候使用 先判断后执行,调整语句在代码块中体现。 while(1)表示为无限循化。 3.3 Do {语句块}while(条件);同 3.2; - 9 - ganbin@tarena.com.cn 唯一的区别是该循环语句代码块至少要被执行一次; 先执行后判断 continue:提前终止本次循环直接进入下一次循环; 3.4 java 中的循环标号 labe:for(int i=0;i<10;i++){ for(int a=0;a<10;a++){ break labe; } } break labe:直接跳出同标号循环层 4、条件运算符的自动类型提升问题。 二、java 中的数组 1. 数组的定义 分为两部分:数组引用(声明) int[] a; int a[]; 数组空间(初始化)a = new int[5]; 2. 数组在分配存储空间后,系统会自动为数组的每个元素初 始化为 0; 3. 定义数组,分配存储空间和初始化数组可以放在一个语句 中,如: int[] a = {10,20,30} 对比:int[] a = new int[3];a[0] = 10;a[1] = 20;a[2] = 30; - 10 - ganbin@tarena.com.cn 4. 在 java 中一个数组就是一个对象,只要是对象就是在堆空 间存放。 注:在 java 中只有堆空间,栈空间,代码空间。 5. 数组长度可以用 数组名.length 来取得. 注:二维数组用.length 取得的长度是其一维数组的长度。 6. 两个数组之间的拷贝:System.arraycopy(a,0,b,0,length) 表示将 a 数组从 0 号位置开始的 length 个元素依次拷贝到 b 数组中(从 0 号位置开始)。 7. 在 java 中二维数组本质上就是一维数组的数组。所以 java 中的二维数组可以是不对称的。Java 中只有一维数组的内 存地址空间是连续的而二维数组的空间可以不连续。 (1)、二维数组声明和初始化 int[][] a;//声明一个二维数组 a = new int[3][];//该二维数组包含三个一维数组对象 而每个一维数组对象长度可以不同所以第二个 【】中的长度可以不填 a[0] = new int[5];//第一列数组长度为 5 a[1] = new int[3]; //第二列数组长度为 3 a[0][0] = 1;//将第一个数组的第一个元素初始化 1; 8. 介绍一个关于数组的小技巧 在我们使用数组时,我们可以用一个 index 辅助变量来 配合数组使用,表示其有效数据的个数,同时用来表示 - 11 - ganbin@tarena.com.cn 数组下一个可插入位置的下标。 三、 java 中的对象 声明:Student s ; 这时我们只是说明 s 是一个能够指向 Student 类型的引 用(相当与 C++中的针),并没有创建一个对象。所以 我们不能对 s 做任何操作。 初始化:s = new Student(); 向系统申请一块存储空间(地址空间),该地址空间保 存的是一个 Student 类型的数据。而 s 中保存的就是 该地址空间的首地址。 这里大家可能还是不太好理解,那么我们给变量来下一个定义 什么叫变量:变量就是内存空间中一块具有固定长度的,用 来保存数据的地址空间。(s 也是一个变量) 一个对象可以有多个引用指向。 Student[] s = new Student[3]只是相当于声明一个长度为 3 的 Student 类型的数组。 四、 实例变量和局部变量 实例变量:1、在一个类中,任何方法之外定义的变量; 2、从面向对象的思想来说我们又把实例变量成为一 个类的属性。 - 12 - ganbin@tarena.com.cn 3、实例变量在没有符初值时系统会自动帮我们做初 始化:整型数据初始化为 0,布尔型数据初始化 为 false,对象类型初始化为 null。 局部变量:1、在方法内定义的变量叫局部变量。 2、局部变量使用前必须初始化,系统不会自动给局 部变量做初始化。 3、局部变量的生命范围在他所在的代码块,在重合 的作用域范围内不允许两个局部变量命名冲突。 注:局部变量与实例变量允许同名,在局部变量的作用域内, 其优先级高于实例变量。我们可以用 this.实例变量名以区 分局部变量。 Day03 一、 java 中的自动类型提升问题。 public class test1{ public static void main(String[] args){ byte a = 1; byte b = 2; byte c = (byte)(a+b); System.out.println(c); } } 二进制是无法精确的表示 0.1 的。 进行高精度运算可以用 java.math 包中 BigDecimal 类中的方法。 自动类型提升又称作隐式类型转换。 - 13 - ganbin@tarena.com.cn 二、在 java 中对面向对象(OO)的要求 1.对象是客观存在的,万物皆对象。 . (注:看不见的对象并不表示该对象不存在,比如说事件); 2. 简单性:采用面向对象方法可以使系统各部分各司其职各尽 所能。 3. 复用性:对象的功能越简单其可重用性越高。 4. 弱耦合性:各司其职各尽所能。 5. 高内聚性:一个对象独立完成一个功能的能力 6. 类是一类事务的共性,是人类主观认识的一种抽象,是对象 的模板。 三、面向过程与面向对象的对比 面向过程:先有算法,后有数据结构。先考虑怎么做。 面向对象:先有数据结构,后有算法。先考虑用什么做。 四、java 中方法的声明(分为五个部分) 1. 方法的修饰符(可以有多个,且顺序无关) 2. 方法的返回值类型 3. 方法名 4. 方法的参数表 5. 方法允许抛出的列外(异常) - 14 - ganbin@tarena.com.cn 注:编译器只能做语法上的检查,而不能进行逻辑上的检查。 Java 中不允许有废话。 五、 java 中的重载(Overload) 1、相同方法名,不同参数表。 2、方法重载时,对于参数的匹配有个向上就近原则。(这 样可以节省栈空间资源); 3、为什么面向对象中要有方法重载? 方法的重载使同一类方法由于参数造成的差异对 于对象的使用者是透明的。对象的使用者只负责把参 数交给对象,而具体怎么实现由对象内部决定。 4、Java 中的运算符重载 java 中唯一重载的运算符是 String 类型的“+”号,任 何类型+String 类型结果都为 Stirng 类型。 5、注意点:重载不仅出现在同一个类中,也可以出现在父 子类中。 六.Java 中创建对象的步骤 1、 分配空间 2、 初始化属性 3、 调用构造方法 注:构造方法不能手工调用,在对象的生命周期内构造方法只 - 15 - ganbin@tarena.com.cn 调用一次。 七、java 中的构造方法 1、 特点:没有返回值,方法名与类名相同。 2、 在不写构造方法时,系统会自动生成一个无参的构造方法。 3、 请养成在每个类中自己加上无参构造方法的习惯。 八、对象和对象引用的区别 对象好比一台电视机,对象引用好比电视机遥控。对象引用中存 的是对象的地址。多个对象引用中存放的是同一个地址,表示该对 象被多个对象引用所引用。 九、 this 表示当前对象 谁调用该方法,在这一时刻谁就是该方法的当前对象 用 this 来区分实例变量和局部变量。 this()表示调用本类的其他构造方法,且只能放在一个方法中的第 一行第一句。 十、 参数传递 在 java 方法传参过程中简单类型是按值传递,对象类型是按引 用传递。 按值传递传递的是数据的副本。 - 16 - ganbin@tarena.com.cn 按引用传递传递的是保存该数据的地址 十一、封装 1.定义:封装指的是一个对象的内部状态对外界是透明的,对象 与对象之间只关心对方有什么方法,而不关心属性。 封装使实现的改变对架构的影响最小化。 2.原则:装使对象的属性尽可能的私有,根据需要配上相应的 get/set 方法,对象的方法尽可能的公开。该隐藏的一定 要隐藏,该公开的一定要公开。 3.方法公开的使声明而不是实现。使方法实现的改变对架构的影 响最小化。 4.访问控制从严到宽 private :仅本类成员可见 default :本类+同包类可见(默认) protected:本类+同包+不同包的子类 public :公开 注:这里的同包指的是跟父类所在的包相同。 5、完全封装:属性全部私有,并提供相应的 get/set 方法。 Day04 一、 继承 1. 定义:基于一个已存在的类构造一个新类。继承已存在的 - 17 - ganbin@tarena.com.cn 类就是复用这些类的方法合属性,在此基础上,还可以在新类 中添加一些新的方法和属性。 2. 父类到子类是从一般到特殊的关系。 3. 继承用关键字 extends dog extends Animal :表示狗类继承了动物类 4. Java 中只允许单继承(java 简单性的体现) 父子类之间的关系是树状关系。(而多继承是网状关系) 5. 父类中的私有属性可以继承但是不能访问。 也可以说父类中的私有属性子类不能继承。 6. 原则:父类放共性,子类放个性。 7. 构造方法不能被子类继承。 二、带继承关系的对象创建的过程 1. 递归的构造父类对象 2. 分配空间 3. 初始化属性 4. 调用本类的构造方法 三、super 关键字 1. Super()表示调用父类的构造方法 2. Super()也和 this 一样必须放在方法的第一行第一句。 3. Super.表示调用父类的方法或属性。例:super.m(); - 18 - ganbin@tarena.com.cn 4. Super 可以屏蔽子类属性和父类属性重名时带来的冲突 5. 在子类的构造函数中如果没有指定调用父类的哪一个构造 方法,那么就会调用父类的无参构造方法,即 super()。 四、白箱复用和黑箱复用 1.白箱复用:又叫继承复用,子类会继承父类所有的东西, 从某种程度上说白箱复用破坏了封装。是一种 is a 的关系。 例:class Liucy{ public void teachCpp(){ System.out.println("Teach Cpp"); } public void chimogu(){ } } class Huxy extends Liucy{ } 2、黑箱复用:又叫组合复用,是一种 has a 的关系。 例:class Liucy{ public void teachCpp(){ System.out.println("Teach Cpp"); } public void chimogu(){ } } class Huxy { private Liucy liucy = new Liucy(); public void teachCpp(){ liucy.teachCpp(); } } 原则:组合复用取代继承复用原则。 - 19 - ganbin@tarena.com.cn 使我们可以有机会选择该复用的功能。 五、多态 1. 定义:所谓多态是指一个对象可以有多种形态,换句话说 多态使我们可以把一个子类对象看作是一个父类对象类型 ( 例:father A = new child() ) 。多态指的是编译时的类型变 化,而运行时类型不变。 2. 多态分为两种:编译时多态和运行时多态。 编译时类型:定义时类型(主观概念)把它看作什么。 运行时类型:真实类型(客观概念) 实际上他是什么。 重载又叫编译时多态,覆盖又称运行时多态。 在方法重载的情况下,参数类型决定于编译时类型。 3. 多态的作用:在我们需要一类对象的共性时,我们可以很 容易的抽取。并且可以屏蔽不同子类对象之间我们所不关心的 差异。多态使我们有机会写出更通用的代码,以适应需求的不 断变化 4. 多态常见的用法: (1)、多态用在方法的参数上 (2)、多态用在方法的返回类型上 5. 运行时多态的三原则: (1)、对象不变(改变的是主观认识) (2)、对于对象的调用只能限于编译时类型的方法。 (3)、在程序的运行时,动态类型判定。运行时调用运行时类 - 20 - ganbin@tarena.com.cn 型,即他调用覆盖后的方法。 六、java 中的覆盖(Override) 1、 参数表、方法名必须完全相同,访问修饰符要求子类 宽于父类。返回值类型在 JDK5.0 以前要求完全相同, 5.0以后可以父类返回一个对象a,子类返回一个该对象 a 的子类也是覆盖。子类方法覆盖父类方法时要求子 类方法的访问修饰符宽于或等于父类的访问修饰符。 2、 为什么面向对象中要有方法覆盖? 覆盖允许子类用自己特色的方法去替换调父类已有的 方法。 3、 父类中的私有方法与子类中任何方法不够成覆盖关系, 也就是说只有父类被子类继承过来的方法,才有可能与 子类自己的方法构成覆盖关系。 4、少覆盖原则:如果子类覆盖了父类过多的方法,那么我们要重 新思考一下这两个类之间到底是不是继承关系。 注:子类的属性和父类的属性同名时叫遮盖(区覆盖) 属性的遮盖是没有多态的。 七、关系运算符:instanceof 1. boolean c = a instanceof b; a:对象变量;b:类名;c:逻辑型返回值。 - 21 - ganbin@tarena.com.cn 如果可以把 a 对象看作是 b 类型,那么返回真。否则返回假。 2. instanceof 一般用于在强制类型转换之前判断对象变量是否 可以强制转换为指定类型。 String [] args 命令行参数在用 java 命令运行程序时输入: 如:java TestOverLoad 参数 1 参数 2 参数 3。。。。。。。 Day05 一、static 修饰符 1. 可以修饰属性、方法、初始代码块,成为类变量、静态方法、 静态初始化代码块。 注:初始代码块是在类中而不再任何方法之内的代码块。 2. 类变量、静态方法、静态初始化代码块与具体的某个对象无关, 只与类相关,是全类公有的。在类加载时初始化。 3. 类加载:虚拟机通过 CLASSPATH 从磁盘上找到字节码文件, 并将字节码文件中的内容通过I/O流读到虚拟机并保存的过程。 在虚拟机的生命周期中一个类只被加载一次。 注:Java 命令的作用是启动 JVM。 4. Static 定义的时一块为整个类共有的一块存储区域,其发生变化 时访问到的数据都是经过变化的。 5. 为什么主方法必须是静态的? - 22 - ganbin@tarena.com.cn 主方法是整个应用程序的入口,JVM 只能通过类名去调用主方 法。 6. 类变量和静态方法可以在没有对象的情况下用:类名.方法名 (或属性名)来访问。 7. 静态方法不可被覆盖(允许在子类中定义同名的静态方法,但 是没有多态);父类如果是静态方法,子类不能覆盖为非静态方 法。父类如果是非静态方法,子类不能覆盖为静态方法。 争论:静态方法可以覆盖但是没有多态。 思考:没有多态的覆盖叫覆盖吗? 在静态方法中不允许调用本类中的非静态成员。 8. 静态初始化代码块只在类加载的时候运行一次,以再也不执行 了。所以静态代码快一般被用来初始化静态成员。 9. 不加 static 为动态初始化代码块,在创建对象时被调用(在构 造函数之前)。 10. 最后要注意的一点就是 Static 不能修饰局部变量。 二、 什么时候类加载 第一次需要使用类信息时加载。 类加载的原则:延迟加载,能不加载就不加载。 触发类加载的几种情况: (1)、调用静态方法时会加载静态方法真正所在的类。 例:通过子类调用父类的静态方法时,只会加载父类而不 - 23 - ganbin@tarena.com.cn 会加载子类。 (2)、调用静态初始化代码块时要加载类。 (3)、加载子类时必定会先加载父类。 (4)、构造对象的时候会加载。 (5)、调用静态属性时会加载类。 注:如果静态属性有 final 修饰时,则不会加载。 例:public static final int a =123; 但是如果上面的等式右值改成表达式(且该表达式在编 译时不能确定其值)时则会加载类。 例:public static final int a = math.PI 三、final 修饰符 1. final 可以用来修饰类、属性和方法。 2. final修饰一个属性时,该属性成为常量。 (1)对于再构造方法中利用 final 进行赋值时候,此时在 构造之前系统设置的默认值相对于构造方法失效。 (2)对于实例常量的赋值有两次机会 在初始化的时候通过声明赋值 在构造的时候(构造方法里)赋值 注:不能在声明时赋值一次,在构造时再赋值一次。 注意:当 final 修饰实例变量时,实例变量不会自动初始化 为 0; - 24 - ganbin@tarena.com.cn 3. Final 修饰方法时,该方法成为一个不可覆盖的方法。这样 可以保持方法的稳定性。 如果一个方法前有修饰词 private 或 static,则系统会自动在 前面加上 final。即 private 和 static 方法默认均为 final 方法。 4. Final 常常和 static、public 配合来修饰一个实例变量,表示 为一个 全类公有的公开静态常量。 例:pubic static final int a = 33; 在这种情况下属性虽然公开了,但由于是一个静态常量所以 并不算破坏类的封装。 5. Final 修饰类时,此类不可被继承,即 final 类没有子类。 一个 final 类中的所有方法默认全是 final 方法。 Fianl 不能修饰构造方法,构造方法不能被继承更谈不上被 子类方法覆盖。 四、 关于 final 的设计模式:不变模式 1、不变模式:一个对象一旦产生就不可能再修改(string 就是 典型的不变模式); 通过不变模式可以做到对象共享; 2、池化思想:用一个存储区域来存放一些公用资源以减少存储 空间的开销。 例:在 String 类中有个串池(在代码区)。 (1) 如果用 Stirng str = “abc”来创建一个对象时,则系统会先 - 25 - ganbin@tarena.com.cn 在串池中寻找有没有“abc”这个字符串。如果有则直接 将对象指向串池中对应的地址,如果没有则在串池中创 建一个“abc”字符串。 所以:String str1 = “abc”; String str2 = “abc”; Str1 = = str2 返回值是 ture;他们的地址是一样 的。也就是说 str1 和 str2 都指向了代码空间中相同的一 个地址,而这个地址空间保存就是是字符串”abc”; (2) 如果用 String str = new String(“abc”)则直接在堆空间开 辟一块存储空间用来存放”abc”这个字符串。 所以:String str1 = new String(“abc”); String str2 = new String(“abc”); Str1 = = str2 返回值是 false;他们的地址是不一 样的。也就是说 str1 和 str2 分别指向了堆空间中不同的 两个地址,而这两个地址空间保存的都是字符串”abc”; 4、 java.lang 下的 StringBuffer 类。 对于字符串连接 String str=”1”+”2”+”3”+”4”; 产生: 12 123 1234 会在串池中产生多余对象,而真正我们需要的只有最后 - 26 - ganbin@tarena.com.cn 一个对象,用这种方式进行字符串连接时,不管在时间 上还是在空间上都会造成相当大的浪费。所以我们应该 使用 StringBuffer(线程安全的) 或者 StringBuilder(线 程不安全的) 解决方案: String s; StringBuffer sb = new StringBuffer(“1”); Sb.append(“2”); Sb.append(“3”); Sb.append(“4”); S = sb.toString(); 解决后的方案比解决前在运行的时间上相差 2 个数量级。 五、abstract 修饰符 1. 可用来修饰类、方法 2. abstract 修饰类时,则该类成为一个抽象类。抽象类不可生 成对象(但可以有构造方法留给子类使用),必须被继承使 用。 抽象类可以声明,作为编译时类型,但不能作为运行时类型。 Abstract 永远不会和 private,static,final 同时出现。 3. Abstract 修饰方法时,则该方法成为一个抽象方法,抽象方 法没有实现只有定义,由子类覆盖后实现。 比较:private void print(){};表示方法的空实现 abstract void print();表示方法为抽象方法,没有实现 4. 抽象方法从某中意义上来说是制定了一个标准,父类并不实 现,留给子类去实现。 - 27 - ganbin@tarena.com.cn 注:抽象类中不一定要有抽象方法,但有抽象方法的类一 定是抽象类。 六、 关于抽象类的设计模式:模板方法 灵活性和不变性 在下面这个例子种父类(抽象类)指定了一个标准,而子类根据 自己的需求做出不同的实现。 例:/****************************************************/ public class TestTemplateMethod{ public static void main(String[] args){ XiaoPin x1 = new ShuoShi(); XiaoPin x2 = new DaPuKe(); x1.act(); x2.act(); } } abstract class XiaoPin{ abstract void jiaoliu(); abstract void xushi(); abstract void gaoxiao(); abstract void shanqing(); public final void act(){ jiaoliu(); xushi(); gaoxiao(); shanqing(); } } class ShuoShi extends XiaoPin{ void jiaoliu(){ System.out.println("顺口溜"); } void xushi(){ System.out.println("写书"); - 28 - ganbin@tarena.com.cn } void gaoxiao(){ System.out.println("打招呼"); } void shanqing(){ System.out.println("二人传"); } } class DaPuKe extends XiaoPin{ void jiaoliu(){ System.out.println("大家好"); } void xushi(){ System.out.println("老同学见面"); } void gaoxiao(){ System.out.println("打扑克"); } void shanqing(){ System.out.println("马家军"); } } /*******************************************************/ Day06 一、接口(interface) 1、 定义:接口不是类,而是一组对类需求的描述,这些类 要遵从接口描述的统一格式进行定义。定义一个接口用 关键字 interface。 例:public interface a{……} 2、 接口是一种特殊的抽象类。在一个接口中,所有的方法 为公开、抽象的方法,所有的属性都是公开、静态、常 量。所以接口中的所有属性可省略修饰符:public static - 29 - ganbin@tarena.com.cn final,接口中所有的方法可省略修饰符:public abstract。 3、 一个类实现一个接口必须实现接口中所有的方法,否则 其为一抽象类。并且在实现类中的方法要加上 public(不 能省略)。实现接口用关键字 implements. 所谓实现一个接口就是实现接口中所有的方法。 例:class Aimple implements A{……..}; 4、 一个类除了继承另一个类外(且只能继承一个类),还 可 以实现多个接口(接口之间用逗号分割)。这样可以实现 变相的多继承。 例:class Aimple extends Arrylist implements A,B,C{…} 5、 不能用“new 接口名”来实例化一个接口,但可以声明 一个接口。 6、 接口与接口之间可以多继承。 例:interface face1 extends face2,face3{} 7、 接口的作用 (1)、间接实现多继承。 用接口来实现多继承并不会增加类关系的复杂 度。因为接口终归不是类,与类不在一个层次上, 是在类的基础上进行再次抽象。 父类:主类型 接口:副类型 典例:相声届师父(主)和干爹(副) (2)、允许我们为一个类定义出混合类型。 - 30 - ganbin@tarena.com.cn (3)、通过接口制定标准 接 口:标准的定义 定义标准 接口的调用者:标准的使用 使用标准 接口的实现类:标准的实现 实现标准 接口的回调:先有接口的使用者,再有接口的 实现者,最后把接口的实现者的对象传到接口的使 用者中,并由接口的使用者通过接口来调用接口实 现者的方法。这就是接口回调。 例:sun 公司提供一套访问数据库的接口(标准), java 程序员访问数据库时针对数据库接口编 程。接口由各个数据库厂商负责实现。 (4)、解耦合作用:采用接口可以最大限度的做到弱耦 合,将标准的实现者与标准的制定者隔离(例: 我们通过 JDBC 接口来屏蔽底层数据库的差异) 8、 接口的编程设计原则 (1)、尽量针对接口编程(能用接口就尽量用接口) (2)、接口隔离原则(用若干个小接口取代一个大接口) 这样可以只暴露想暴露的方法,实现一个更高层 次的封装。 9、 注意点: (1)、一个文件只能有一个 public 接口,且与文件名相 同。 - 31 - ganbin@tarena.com.cn (2)、在一个文件中不能同时定义一个 public 接口和一 个 public 类。 (3)、接口与实体类之间只有实现关系,没有继承关系; 抽象类与类之间只有继承关系没有实现关系。接 口与接口之间只有继承关系,且允许多继承。 (4)、接口中可以不写 public,但在子类实现接口的过程中 public 不可省略。 二、接口 VS 抽象类 1、接口中不能有具体的实现,但抽象类可以。 2、一个类要实现一个接口必须实现其里面所有的方法,而抽 象类不必。 3、通过接口可以实现多继承,而抽象类做不到。 4、接口不能有构造方法,而抽象类可以。 5、实体类与接口之间只有实现关系,而实体类与抽象类只有 继承关系,抽象类与接口之间既有实现关系又有继承关系。 6、接口中的方法默认都是公开抽象方法,属性默认都是公开 静态常量,而抽象类不是。 三、Object 类 1、 object 类是类层次结构的根类,他是所有类默认的父类。 2、 object 类中的三个方法。 - 32 - ganbin@tarena.com.cn (1)、finalize() 当一个对象被垃圾收集的时候,最后会由 JVM 调用 这个对象的 finalize 方法; 注意:这个方法一般不用,也不能将释放资源的代 码放在这个方法里; (2)、toString() 返回一个对象的字符串表示形式。打印一个对象其 实就是打印这个对象 toString 方法的返回值。 我们可以在自己的类时覆盖 toString()方法,从而打 印我们需要的数据。Public String toString(){……} (3)、equals(Object o) 该方法用来判断对象的值是否相等。但前提是类中 覆盖了 equals 方法。Object 类中的 equals 方法判断的其 实还是地址。这里注意:String 类已经覆盖了 equals 方 法了,所以我们能使用 equals 来判断 String 对象的值是 否相等。 下面是覆盖 equals 方法的标准流程: public Boolean equals(Object o){ /**第一步:现判断两个对象地址是否相等*/ if(this = = o) return true; /**第二步:如果参数是 null 的话直接返回 false;*/ if(o = = null) return false; - 33 - ganbin@tarena.com.cn /**第三步:如果两个对象不是同一个类型直接返回 false*/ if( !(o instanceof Student) ) return false; /**第四步:将待比较对象强转成指定类型,然后自定 义比较规则*/ Student s = (Student)o; If(s.name.equals(this.name)&&s.age==this.age) return true; else return false } (4)、equals 的特性:自反性、对称性、一致性、传递性。 Day07 一、封装类 JAVA 为每一个简单数据类型提供了一个封装类,使每个简单数据 类型可以被Object 来装载。 除了 int 和 char,其余类型首字母大写即成封装类 int Integer char Character int Integer String 之间的类型转换(最常用的) int a =12; int 到 Integer Integer aa = new Integer(a); - 34 - ganbin@tarena.com.cn Integer 到 int int i = aa.intValue(); Int 到 String String str = String.valueOf(i); String 到 int int ii = Integer.parseInt(str); Integer 到 String String str = aa.toString() String 到 Integer Integer bb = Integer.valueOf(str) 二、 内部类(非重点) 1.定义:定义在其他类中的类,叫内部类。内部类是一种编译时的 语法。编译后生成的两个类时独立的两个类。内部类配合 接口使用,来强制做到弱耦合(局部内部类,或私有成员 内部类)。 2.内部类存在的意义在于可以自由的访问外部类的任何成员(包括 私有成员),所有使用内部类的地方都可以不用内部类,使用内 部类可以使程序更加的简洁(以牺牲程序的可读性为代价),便 于命名规范和划分层次结构。 3.内部类作为外部类的一个成员,并且依附于外部类而存在的。 4.内部类可为静态,可用PROTECTED 和PRIVATE 修饰。(而 外部类不可以:外部类只能使用PUBLIC和DEFAULT)。 5.内部类的分类:成员内部类、局部内部类、静态内部类、匿名内 部类。 ① 成员内部类:作为外部类的一个成员存在,与外部类的属性、方 法并列。 - 35 - ganbin@tarena.com.cn 内部类和外部类的实例变量可以共存。 在内部类中访问实例变量:this.属性 在内部类访问外部类的实例变量:外部类名.this.属性。 对于一个名为outer 的外部类和其内部定义的名为inner 的内部类。 编译完成后出现outer.class 和outer$inner.class 两类。 成员内部类不可以有静态属性,这是因为静态属性是在加载类的时候 创建,这个时候内部类还没有被创建。 如果在外部类的外部访问内部类,使用out.inner. 建立内部类对象时应注意: 在外部类的内部可以直接使用inner s=new inner();(因为外部类知道 inner 是哪个类,所以可以生成对象。) 而在外部类的外部,要生成(new)一个内部类对象,需要首先建立 一个外部类对象(外部类可用),然后在生成一个内部类对象。 Outer.Inner in=Outer.new.Inner()。 相当于:Outer out = new Outer(); Outer.Inner in = out.new Inner(); 错误的定义方式: Outer.Inner in=new Outer.Inner()。 ② 局部内部类:在方法中定义的内部类称为局部内部类。 与局部变量类似,在局部内部类前不加修饰符public 和private,其范围为定义它的代码块。 注意:局部内部类不仅可以访问外部类实例变量,还可以访问外部类 - 36 - ganbin@tarena.com.cn 的局部变量(但此时要求外部类的局部变量必须为final) 在类外不可直接生成局部内部类(保证局部内部类对外是不可 见的)。 要想使用局部内部类时需要生成对象,对象调用方法,在方法 中才能调用其局部内部类。 ③ 静态内部类:(注意:前三种内部类与变量类似,所以可以对照 参考变量) 静态内部类定义在类中,任何方法外,用static 定义。 静态内部类只能访问外部类的静态成员。 生成(new)一个静态内部类不需要外部类成员:这是静态内部类和 成员内部类的区别。静态内部类的对象可以直接生成: Outer.Inner in=new Outer.Inner(); 对比成员内部类:Outer.Inner in = Outer.new Inner(); 而不需要通过生成外部类对象来生成。这样实际上使静态内部类成为 了一个顶级类。 静态内部类不可用private 来进行定义。例子: 对于两个类,拥有相同的方法: /*********************************************************/ public class TestRobot{ public static void main(String[] args){ Robot r = new Robot(); r.run(); r.getHeart().run(); } } - 37 - ganbin@tarena.com.cn abstract class People{ abstract void run(); } interface Machine{ void run(); } class Robot extends People{ class Heart implements Machine{ public void run(){ System.out.println("发动机跑"); } } public void run(){ System.out.println("机器人跑"); } public Machine getHeart(){ return new Heart(); } } /*************************************************************************/ 此时run()不可直接实现。 注意:当类与接口(或者是接口与接口)发生方法命名冲突的时候, 此时必须使用内部类来实现。这是唯一一种必须使用内部类的 情况。用接口不能完全地实现多继承,用接口配合内部类才能 实现真正的多继承。 ④ 匿名内部类: 【1】 匿名内部类是一种特殊的局部内部类,它是通过匿名类实现 接口。 【2】 不同的是他是用一种隐含的方式实现一个接口或继承一个 类,而且他只需要一个对象 【3】 在继承这个类是,根本就没有打算添加任何方法。 - 38 - ganbin@tarena.com.cn 【4】 匿名内部类大部分情况都是为了实现接口的回调。 注:一个匿名内部类一定是在new 的后面,用其隐含实现一个接口 或实现一个类,没有类名,根据多态,我们使用其父类名。 因其为局部内部类,那么局部内部类的所有限制都对其生效。 匿名内部类是唯一一种无构造方法类。 注:这是因为构造器的名字必须合类名相同,而匿名内部类没有类名。 匿名内部类在编译的时候由系统自动起名Out$1.class。 因匿名内部类无构造方法,所以其使用范围非常的有限。 接口+内部类才能真正实现多继承。 一个关于匿名内部类的例子: /******************************************************/ public class test{ public static void main(String[] args){ B.print(new A(){ public void getConnection(){ System.out.println("Connection...."); } }); } } interface A{ void getConnection(); } class B{ public static void print(A a){ a.getConnection(); } } /******************************************************/ - 39 - ganbin@tarena.com.cn 三、 异常 Exception 1. 概念: JAVA 会将所有的错误封装成为一个对象,其 根本父类为 Throwable。异常处理可以提高我们系统的 容错性。 Throwable 有两个子类:Error 和 Exception。 Error:一般是底层的不可恢复的错误。 Object ↑ Throwable ↑ |ˉˉˉˉˉˉˉˉ| Error Exception ↑ |ˉˉˉˉˉˉˉ| RuntimeException 非 Runtime exception 2. Exception 分类:Runtime exception(未检查异常)和 非 Runtime exception(已检查异常)。 未检查异常是因为程序员没有进行必要的检查,因为他 的疏忽和错误而引起的异常。一定是属于虚拟机内部的 异常(比如空指针)。 几个常见的未检查异常: 1) java.lang.ArithmeticException 如:分母为 0; 2) java.lang.NullPointerException 如:空指针操作; 3) java.lang.ArrayIndexoutofBoundsExceptio - 40 - ganbin@tarena.com.cn 如:数组越界; 4) java.lang. ClassCastException 如:类型转换异常; 已检查异常是不可避免的,对于已检查异常必须处理。 3、异常对象的传递。 当一个方法中出现了异常而又没做任何处理,那么这个 方法会返回该异常对象。依次向上层调用者传递,直到传 到 JVM,虚拟机终止运行。(用一句话说就是沿着方法调 用链反向传递) 4、如何来处理异常(这里主要是针对已检查异常) 【1】 throws 消极处理异常的方式。 方法名(参数表)throws 后面接要往上层抛的异常。 表示该方法对指定的异常不作任何处理,直接抛往上一 层。 【2】 积极处理方式 try、catch try {可能出现错误的代码块} catch(exception e){进 行处理的代码} ; 一个异常捕获只会匹配一次 try,catch. 一个异常一旦被捕获就不存在了。 Catch 中要求必须先捕获子类异常再捕获父类异常。 【3】 finally (紧接在 catch 代码块后面) finally 后的代码块是无论如何都会被执行的(除非虚 - 41 - ganbin@tarena.com.cn 拟机退出),所以在 finally 后的代码快里我们一般写 的是释放资源的代码。 Public static int fn(int b){ Try{ Return b/2; }catch(Exception e){ return 0; }finally{ return b; } } 返回的结果是一定是 b; 5、 自定义异常(与一般异常的用法没有区别) class MyException extends Exception{ public MyException(String message){ super(message); } public MyException(){} } 6、如何控制 try 的范围:根据操作的连动性和相关性,如果 前面的程序代码块抛出的错误影响了后面程序代码的运 行,那么这个我们就说这两个程序代码存在关联,应该放 在同一个 try 中。 7、不允许子类比父类抛出更多的异常。 8、断言:只能用于代码调试时用。(一般没什么用) 一个关于断言的列子: /******************************************************/ public class TestAssertion { public static void main(String[] args){ int i = Integer.parseInt(args[0]); assert i==1:"ABCDEFG"; /* - 42 - ganbin@tarena.com.cn 断言语句(表示断言该boolean语句返回值一定为真, 如果断言结果为false就会报Error错误) ":"后面跟出现断言错误时要打印的断言信息。 */ System.out.println(i); } } //java -source 1.4 TestAssertion.java //表示用1.4的新特性来编译该程序。 //java -ea TestAssertion 0 //表示运行时要用到断言工具 /********************************************************/ - 43 - ganbin@tarena.com.cn Day08 《集合框架》 Collection 接口 List 接口 Set 接口 Vector ArrayList LinkedList HashSet SortedSet 接口 TreeSet Map 接口 HashMap SortedMap 接口 TreeMap 一、 集合:集合是一个用于管理其他多个对象的对象 1、Collection 接口:集合中每一个元素为一个对象,这个接口将这 些对象组织在一起,形成一维结构。 2、List 接口:代表按照元素一定的相关顺序来组织(在这个 序列中顺序是主要的),List 接口中数据可重 复。 3、Set 接口:是数学中集合的概念:其元素无序,且不可重复。 - 44 - ganbin@tarena.com.cn - 45 - (正好与List 对应) 4、SortedSet 接口 :会按照数字将元素排列,为“可排序集合”。 5、Map 接口 :接口中每一个元素不是一个对象,而是一个键 对象和值对象组成的键值对(Key-Value)。 6、SortedMap接口:如果一个Map 可以根据key 值排序,则称其为 SortedMap。 注意:在“集合框架”中,Map 和Collection 没有任何亲 缘关系。 •Map 的典型应用是访问按关键字存储的值。它支持一 系列集合操作的全部,但操作的是键-值对,而不 是单个独立的元素。因此Map 需要支持get() 和 put() 的基本操作,而Set 不需要。 •返回Map 对象的Set 视图的方法: Set set = aMap.keySet() List Set SortedSet Map SortedMap 存放元素 Object Object Object Object(key)—Object(value) Object(key)—Object(value) 存放顺序 有序 无序 无序 Key 无序 无序,有排序 元素可否重复 可 不可 不可 Key 不可,value 可 Key 不可,value 可 遍历方式 迭代 迭代 迭代 对 Key 迭代 对 Key 迭代 排序方式 Collections.sort() SortedSet 已排序 SortedMap 已对键值排序 各自实现类 ArrayList LinkedList HashSet TreeSet HashMap TreeMap 2、实现 java.lang 包下的 Comparable 接口 在 java 中指定排序规则的方式只有两种:1、实现 java.util 包下的 Comparator 接口 HashSet、HashMap 通过 hashCode(),equals()来判断重复元素 注:以上有序的意思是指输出的顺序与输入元素的顺序一致 《常用集合列表》 - 46 - ganbin@tarena.com.cn ganbin@tarena.com.cn 二、 迭代器:Iterator 1、使用 Iterator 接口方法,您可以从头至尾遍历集合,并安全的从 底层 Collection 中除去元素 2、remove() 方法可由底层集合有选择的支持。当底层集合调用并支 持该方法时,最近一次 next() 调用返回的元素就被除去 3、Collection 接口的iterator() 方法返回一个Iterator 4、Iterator中的hasNext()方法表用于判断元素右边是否还有数据, 返回True 说明有。然后就可以调用next()动作。 5、Iterator中的next()方法会将游标移到下一个元素,并把它所跨 过的元素返回。(这样就可以对元素进行遍历) 6、用于常规 Collection 的 Iterator 接口代码如下: /*迭代遍历*/ List l = new ArrayList(); Iterator it = l.iterator(); while(it.hasNext()){ Object o = it.next(); System.out.println(o); } 注:工具类是指所有的方法都是公开静态方法的类。 Java.util.collections 就是一个工具类; 三、 对集合的排序 1、 我们可以用 Java.util.collections 中的 sort(List l)方 法对指定的 List 集合进行排序;但是如果 List 中存放的是 - - 47 - - ganbin@tarena.com.cn 自定义对象时,这个方法就行不通了,必须实现 Comparable 接口并且指定排序规则。 这里我们再来看一下 sort(List l)方法的内部实现; /**********************************************************/ class Collections2{ public static void sort(List l){ for(int i=0;i0){ Collections.swap(l,i,j); } } } } } 注:其实用的算法就是个冒泡排序。 /******************************************************/ 2、 实现 Java.lang.Comparable 接口,其实就是实现他的 public int compareTo(Object o)方法; 比较此对象与指定对象的顺序。如果该对象小于、等于或大 于指定对象,则分别返回负整数、零或正整数。 其规则是当前对象与o 对象进行比较,其返回一个int 值, 系统根据此值来进行排序。 如当前对象>o 对象,则返回值>0; 如当前对象=o 对象,则返回值=0; - - 48 - - ganbin@tarena.com.cn 如当前对象 l = new ArrayList(); :表示该集合中只能存放 String 类型对象。 3、 使用了泛型技术的集合在编译时会有类型检查,不再需要强制 类型转换。String str = l.get(2); 注:一个集合所允许的类型就是这个泛型的类型或这个泛型的 子类型。 4、 List l = new ArrayList× 必须类型一致,泛型没有多态 - - 89 - - ganbin@tarena.com.cn 5、 泛型的通配符 泛型的通配符表示该集合可以存放任意类型的对象。 static void print( Cllection c ){ for( Object o : c ) out.println(o); } 6、 带范围的泛型通配符 (1)、向下匹配: 表示该集合元素可以为 Number 类型及其子类型(包括接口) (2)、向上匹配: 表示该集合元素可以为 Number 类型及其父类型 7、 泛型方法 在返回值与修饰符之间可以定义一个泛型方法 public static void copy (T[] array,Stack sta){…..} 8、 不能使用泛型的情况: (1)、带泛型的类不能成为 Throwable 类和 Exception 类的子类 因为 cathc()中不能出现泛型。 (2)、不能用泛型来 new 一个对象 如:T t = new T(); (3)、静态方法不能使用类的泛型,因为静态方法中没有对象的概 念。 9、 在使用接口的时候指明泛型。 class Student implements Comparable{…….} - - 90 - - ganbin@tarena.com.cn Day17 一、CoreJava 5.0 的注释 1、 定义:Annotation 描述代码的代码(区:描述代码的文字) 给机器看 给人看的 2、 注释的分类: (1)、标记注释:没有任何属性的注释。@注释名 (2)、单值注释:只有一个属性的注释。@注释名(value=___) 在单值注释中如果只有一个属性且属性名就是 value, 则“value=”可以省略。 (3)、多值注释:有多个属性的注释。多值注释又叫普通注释。 @注释名(多个属性附值,中间用逗号隔开) 3、 内置注释: (1)、Override(只能用来注释方法) 表示一个方法声明打算重写超类中的另一个方法声 明。如果方法利用此注释类型进行注解但没有重写超类 方法,则编译器会生成一条错误消息。 (2)、Deprecated 用 @Deprecated 注释的程序元素,不鼓励程序员 使用这样的元素,通常是因为它很危险或存在更好的选 择。在使用不被赞成的程序元素或在不被赞成的代码中 执行重写时,编译器会发出警告。 - - 91 - - ganbin@tarena.com.cn (3)、SuppressWarnings(该注释无效) 指示应该在注释元素(以及包含在该注释元素中的 所有程序元素)中取消显示指定的编译器警告。 4、 自定义注释 5、 注释的注释:java.lang. annotation 包中 (1)、Target:指示注释类型所适用的程序元素的种类。 例:@Target(value = {ElementType.METHOD}); 说明该注释用来修饰方法。 (2)、Retention:指示注释类型的注释要保留多久。如果注释 类型声明中不存在 Retention 注释,则保留 策略默认为 RetentionPolicy.CLASS。 例:Retention(value = {RetentionPolicy.xxx} 当 x 为 CLASS 表示保留到类文件中,运行时抛弃。 当 x 为 RUNTIME 表示运行时仍保留 当 x 为 SOURCE 时表示编译后丢弃。 (3)、Documented:指示某一类型的注释将通过 javadoc 和类 似的默认工具进行文档化。应使用此类型来 注释这些类型的声明:其注释会影响由其客 户端注释的元素的使用。 (4)、Inherited:指示注释类型被自动继承。如果在注释类型声 明中存在 Inherited 元注释,并且用户在某一 类声明中查询该注释类型,同时该类声明中 - - 92 - - ganbin@tarena.com.cn 没有此类型的注释,则将在该类的超类中自 动查询该注释类型。 注:在注释中,一个属性既是属性又是方法。 二、Java5.0 中的并发 1、 所在的包:Java.util.concurrent 2、 重写线程的原因: (1) 、何一个进程的创建(连接)和销毁(释放资源)的过程都 是一个不可忽视的开销。 (2) 、run 方法的缺陷:没有返回值,没有抛例外。 3、 对比 1.4 和 5.0 的线程 5.0 1.4 ExecutorService 取代 Thread Callable Future 取代 Runnable Lock 取代 Synchronized SignalAll 取代 notifyAll() await() 取代 wait() - - 93 - -
还剩92页未读

继续阅读

下载pdf到电脑,查找使用更方便

pdf的实际排版效果,会与网站的显示效果略有不同!!

需要 10 金币 [ 分享pdf获得金币 ] 0 人已下载

下载pdf

pdf贡献者

cheishxing

贡献于2012-08-11

下载需要 10 金币 [金币充值 ]
亲,您也可以通过 分享原创pdf 来获得金币奖励!