1、疯狂 java 讲义笔记一、Java 概述1.java 编译产生与平台无关的字节码(*.class 文件) ,再在 JVM 里面执行。2.JVM 是一个抽象的计算机,具有指令集并使用不同的存储区,负责执行指令,还要管理数据、内存和寄存器。3.JVM 细节:指令集、寄存器、类文件的格式、栈、垃圾回收堆、存储区。4.只运行 java 程序可以只安装 JRE,若要开发则要 JDK5.bin 路径下的绝大部分命令都是包装了 tools.jar 文件里的工具类。6.JDK1.5之后可以不用设置 CLASSPATH 环境变量。7.main 方法的 public 和 static 可以交换位置。8.垃圾回收
2、相关:将对象引用设置为 null 将加快垃圾回收;可以通过 System.gc()来建议系统进行垃圾回收;垃圾回收的精确性主要包括 a.精确标记或者的对象 b.精确地定位对象之间的引用关系。二、理解面向对象1.基本特征:a.封装:将对象实现细节隐藏起来,然后通过一些共用方法来暴露该对象的功能b.继承:c.多态:子类对象可以直接赋给父类变量,运行时依然表现出子类的行为特征,这意味着同一个类型的对象在执行同一个方法时,可能表现出多种行为特征。三、数据类型和运算符1.注释,单行注释/ ,多行注释 /* */,文档注释/* . */2.注释中常用标记author 指定 java 程序作者,versio
3、n 指定源文件的版本,deprecated 不推荐使用的方法,param 方法的参数说明信息,return 方法的返回值说明信息,see 参见,关于指定交叉参考的内容,exception 抛出异常类型,throws抛出的异常,和 exception 同意。类或接口文档中的标记see、deprecated、author、version ;方法或构造器文档中的标记see、deprecated、param、return、throws 和exception 等;出现在 Field 文档注释中的有see、deprecated 等java view plain copy print? package ye
4、eku; /* * Description: * 网站: 疯狂 Java 联盟 * Copyright (C), 2001-2012, Yeeku.H.Lee * This program is protected by copyright laws. * Program Name: * Date: * author Yeeku.H.Lee * version 1.0 */ public class JavadocTagTest /* * 一个得到打招呼字符串的方法。 * param name 该参数指定向谁打招呼。 * return 返回打招呼的字符串。 */ public String
5、hello(String name) return name + “,你好!“; 3.标识符中可以包含$符号4.Java 语言指出的类型,基本类型( primitive type):int 等,引用类型(reference type):类、接口、数组、null5.java7中新增了二进制类型。以 0b 或者0B 开头6.特殊的三个浮点数:正无穷大 Double 或 Float 的 POSITIVE_INFINITY 表示,负无穷大NEGATIVE_INFINITY 表示,非数 NaN7.java7中可以在数值中使用下划线。 int binVal = 0B1000_0000_0000_0011;
6、double pi = 3.14_15_92;四、数组1.数组是一种数据类型,它本身市一中引用类型。 int就是一种类型。2.java 数组定义格式 type arrayName 和 type arrayName; 推荐第一种。这样只定义了一个引用变量,没有分配内存空间。3.初始化:a.静态初始化 arrayName= new type element1,element2.,type 与 element 类型相同。也可以 arrayName = element1, element2.b.动态初始化 arrayName= new typelength4.foreach 用于遍历数组和集合 ,fo
7、r (type variableName : array | collection) .,只提供访问,不提供修改,即修改无效。5.基本数据类型数组直接在数组引用的内存存储值,而引用类型数组数组元素是引用,需要再次申请堆内存。6.二维数组的初始化java view plaincopyprint? public class TwoDimensionTest public static void main(String args) /定义一个二维数组 int a; /把 a 当成一维数组进行初始化,初始化 a 是一个长度为4的数组 /a 数组的数组元素又是引用类型 a = new int4; /把
8、a 数组当成一维数组,遍历 a 数组的每个数组元素 for (int i = 0 , len = a.length; i this.name =new Name(name.getFirstName()name.getLastName(); java view plaincopyprint? public Name getName() return newName(name.getFirstName()name.getLastName(); public static void main(String args) Name n = new Name(“悟空“, “孙“); Person p =
9、new Person(n); / Person 对象的 name 的 firstName 值为“悟空“ System.out.println(p.getName().getFirstName(); / 改变 Person 对象 name 的 firstName 值 n.setFirstName(“八戒“); / Person 对象的 name 的 firstName 值被改为“八戒 “ System.out.println(p.getName().getFirstName(); 8.含有抽象方法的类只能被定义成抽象类(直接定义一个抽象方法;继承了一个抽象父类没有完全实现父类包含的抽象方法,以及
10、实现了一个接口,但没有完全实现接口包含的抽象方法) ,final 和 abstract 不能同时使用,static 不能和 abstract 同时使用9.接口中不能包含普通方法,接口中所有方法都是抽象方法。一个接口可以有多个直接父接口,但接口只能继承接口,不能继承类。接口里可以包含 Field(只能是常量) 、方法(只能是抽象实例方法) 、内部类(包括内部接口、枚举)定义。接口中的成员(包括常量、方法、内部类和枚举)都是 public 访问权限,可以省略 public,如果指定访问修饰则只能用 public。接口中的 Field 会自动添加 static 和 final 修饰符,即自动添加 p
11、ublic static final,而且接口中没有构造器和初始化块,必须在定义时指定默认值。接口里的方法总是public abstract 来修饰。接口里定义的内部类、接口、枚举类默认都采用 public static 两个修饰符10.一个类可以继承一个父类,实现多个接口11.内部类成员可以直接访问外部类的私有数据,因为内部类被当成其外部类成员,同一个类成员之间可以相互访问,但外部类不能访问内部类的实现细节12.内部类的文件形式,B 是 A 的内部类,则会生成 A.class 和 A$B.class13.外部类成员变量、内部类成员变量与内部类里方法的局部变量同名,则可通过使用 this,外部
12、类类名.this 作为限定来区分。同过 OutterClass.this.propName 的形式访问外部类的实例 Field,通过 this.propName 的形式访问非静态内部类的实例 Fieldjava view plaincopyprint? public class DiscernVariable private String prop = “外部类的实例变量“; private class InClass private String prop = “内部类的实例变量“; public void info() String prop = “局部变量“; /通过 外部类类名.thi
13、s.varName 访问外部类实例 Field System.out.println(“外部类的 Field 值:“ + DiscernVariable.this.prop); /通过 this.varName 访问内部类实例的 Field System.out.println(“内部类的 Field 值:“ + this.prop); /直接访问局部变量 System.out.println(“局部变量的值:“ + prop); public void test() InClass in = new InClass(); in.info(); public static void main(
14、String args) new DiscernVariable().test(); 14.内部类也满足静态关系,即静态成员不能访问非静态成员,不允许在非静态内部类里定义静态成员15.static 修饰的内部类,属于外部类本身,称为静态内部类。外部类不能直接访问静态内部类的成员,但可以使用静态内部类的类名作为调用者来访问静态内部类的类成员,也可以使用静态内部类对象作为调用者来访问静态内部类的实例成员。java view plaincopyprint? public class AccessStaticInnerClass static class StaticInnerClass privat
15、e static int prop1 = 5; private int prop2 = 9; public void accessInnerProp() /System.out.println(prop1); /上面代码出现错误,应改为如下形式: /通过类名访问静态内部类的类成员 System.out.println(StaticInnerClass.prop1); /System.out.println(prop2); /上面代码出现错误,应改为如下形式: /通过实例访问静态内部类的实例成员 System.out.println(new StaticInnerClass().prop2);
16、16.接口中定义的内部类,默认使用 public static 修饰17.在外部类以外使用非静态内部类:如果在外部类以外的地方访问内部类(包括静态和非静态) ,则内部类不能使用 private 访问控制权限,private 修饰的内部类只能在外部类内部使用,对于使用其他访问控制符修饰的内部类,则能在访问控制符对应的访问权限内使用。java view plaincopyprint? OuterClass.InnerClass varName /在外部类意外定义内部类变量 在外部类以外的地方创建非静态内部类实例java view plaincopyprint? OuterInstance.new
17、InnerConstructor(); java view plaincopyprint? class Out /定义一个内部类,不使用访问控制符, /即只有同一个包中其他类可访问该内部类 class In public In(String msg) System.out.println(msg); public class CreateInnerInstance public static void main(String args) Out.In in = new Out().new In(“测试信息“); /* 上面代码可改为如下三行代码: 使用 OutterClass.InnerCla
18、ss 的形式定义内部类变量 Out.In in; 创建外部类实例,非静态内部类实例将寄存在该实例中 Out out = new Out(); 通过外部类实例和 new 来调用内部类构造器创建非静态内部类实例 in = out.new In(“测试信息“); */ 非静态内部类构造器必须使用外部类对象来调用。18.在外部类以外使用静态内部类java view plaincopyprint? class StaticOut /定义一个静态内部类,不使用访问控制符, /即同一个包中其他类可访问该内部类 static class StaticIn public StaticIn() System.ou
19、t.println(“静态内部类的构造器“); public class CreateStaticInnerInstance public static void main(String args) StaticOut.StaticIn in = new StaticOut.StaticIn(); /* 上面代码可改为如下两行代码: 使用 OutterClass.InnerClass 的形式定义内部类变量 StaticOut.StaticIn in; 通过 new 来调用内部类构造器创建静态内部类实例 in = new StaticOut.StaticIn(); */ 静态内部类只需使用外部类
20、即可调用构造器,而非静态内部类必须使用外部类对象来调用构造器使用静态内部类只要把外部类当成静态内部类的包空间即可。19.匿名内部类适合创建那种只使用一次的类,匿名内部类会立即创建一个该类的实例,匿名内部类必须继承一个父类,或(最多)实现一个接口。匿名内部类不能是抽象类(需要对象实例) ,匿名内部类不能定义构造器(无类名) ,可以定义实例初始化块java view plaincopyprint? new 父类构造器(实参列表) | (实现接口) 匿名内部类的类体 java view plaincopyprint? interface Product java view plaincopyprin
21、t? public double getPrice(); public String getName(); public class AnonymousTest public void test(Product p) System.out.println(“购买了一个“ + p.getName() + “,花掉了“ + p.getPrice(); public static void main(String args) AnonymousTest ta = new AnonymousTest(); /调用 test 方法时,需要传入一个 Product 参数, /此处传入其匿名实现类的实例 t
22、a.test(new Product() public double getPrice() return 567.8; public String getName() return “AGP 显卡“ ; ); 20.通过接口创建匿名内部类时,不能显示创建构造器,只有一个隐式的无参构造器,new 接口名后的括号里不能传入参数值;通过继承父类来创建匿名内部类时,匿名内部类自动拥有和父类相似(相同的形参列表)的构造器。java view plaincopyprint? abstract class Device private String name; public abstract double
23、getPrice(); public Device() public Device(String name) this.name = name; /此处省略了 name 的 setter 和 getter 方法 public void setName(String name) this.name = name; public String getName() return this.name; public class AnonymousInner public void test(Device d) System.out.println(“购买了一个“ + d.getName() + “,花
24、掉了“ + d.getPrice(); public static void main(String args) AnonymousInner ai = new AnonymousInner(); /调用有参数的构造器创建 Device 匿名实现类的对象 ai.test(new Device(“电子示波器“) public double getPrice() return 67.8; ); /调用无参数的构造器创建 Device 匿名实现类的对象 Device d = new Device() /初始化块 System.out.println(“匿名内部类的初始化块.“); /实现抽象方法 p
25、ublic double getPrice() return 56.2; /重写父类的实例方法 public String getName() return “键盘“; ; ai.test(d); 21.匿名内部类内部只能访问外部类的 final 变量22.回调就是某一个方法一旦获得了内部类对象的引用后,就可以在合适的时候反过来去调用外部类实例的方法。所谓回调,就是允许客户类通过内部类引用来调用其外部类的方法java view plaincopyprint? public class TeachableProgrammer extends Programmer public Teachable
26、Programmer() public TeachableProgrammer(String name) super(name); /教学工作依然由 TeachableProgrammer 类定义 private void teach() System.out.println(getName() + “教师在讲台上讲解 .“); private class Closure implements Teachable /* 非静态内部类回调外部类实现 work 方法,非静态内部类引用的作用仅仅是 向客户类提供一个回调外部类的途径 */ public void work() teach(); /返回
27、一个非静态内部类引用,允许外部类通过该非静态内部类引用来回调外部类的方法 public Teachable getCallbackReference() return new Closure(); java view plaincopyprint? public class TeachableProgrammerTest public static void main(String args) TeachableProgrammer tp = new TeachableProgrammer(“李刚“); /直接调用 TeachableProgrammer 类从 Programmer 类继承到的
28、 work 方法 tp.work(); /表面上调用的是 Closure 的 work 方法, /实际上是回调 TeachableProgrammer 的 teach 方法 tp.getCallbackReference().work(); 23.用 enum 定义枚举类,默认继承了 Enum 类,Enum 类实现了 Serializable 和Comparable 两个接口。使用 enum 定义、非抽象的枚举类默认会使用 final 修饰,构造器只能使用 private 访问控制符;枚举类的所有实例必须在枚举类第一行显示列出,系统自动添加 public static final 修饰;枚举类
29、提供了一个 values 方法。java view plaincopyprint? public enum SeasonEnum / 在第一行列出 4个枚举实例 SPRING,SUMMER,FALL,WINTER; java view plaincopyprint? public class EnumTest public void judge(SeasonEnum s) /switch 语句里的表达式可以是枚举值 switch (s) case SPRING: System.out.println(“春暖花开,正好踏青“); break; case SUMMER: System.out.pr
30、intln(“夏日炎炎,适合游泳“); break; case FALL: System.out.println(“秋高气爽,进补及时“); break; case WINTER: System.out.println(“冬日雪飘,围炉赏雪“); break; public static void main(String args) /所有枚举类都有一个 values 方法,返回该枚举类的所有实例 for (SeasonEnum s : SeasonEnum.values() System.out.println(s); /平常使用枚举实例时, /总是通过 EnumClass.variable
31、 形式来访问 new EnumTest().judge(SeasonEnum.SPRING); 23.枚举类的实例只能是枚举值,而不是随意通过 new 来创建枚举对象。每一个实例拥有一套定义的 Fieldbetterjava view plaincopyprint? public enum Gender MALE,FEMALE; private String name; public void setName(String name) switch (this) case MALE: if (name.equals(“男“) this.name = name; else System.out.
32、println(“参数错误“); return; break; case FEMALE: if (name.equals(“女“) this.name = name; else System.out.println(“参数错误“); return; break; public String getName() return this.name; java view plaincopyprint? public class GenderTest public static void main(String args) Gender g = Enum.valueOf(Gender.class ,
33、“FEMALE“); g.setName(“女“); System.out.println(g + “代表:“ + g.getName(); /此时设置 name 值时将会提示参数错误。 g.setName(“男“); System.out.println(g + “代表:“ + g.getName(); bestjava view plaincopyprint? public enum Gender /此处的枚举值必须调用对应构造器来创建 MALE(“男“),FEMALE( “女“); private final String name; /枚举类的构造器只能使用 private 修饰 pr
34、ivate Gender(String name) this.name = name; public String getName() return this.name; 24.枚举类实现接口与普通类一样。这样每个实例都有同样的方法。如果要实现实例方法的差异化,需要让每个枚举值分别来实现该方法java view plaincopyprint? public interface GenderDesc void info(); java view plaincopyprint? public enum Gender implements GenderDesc /此处的枚举值必须调用对应构造器来创建
35、 MALE(“男“) /花括号部分实际上是一个类体部分 public void info() System.out.println(“这个枚举值代表男性“); , FEMALE(“女“) public void info() System.out.println(“这个枚举值代表女性“); ; /其他部分与 codes066.8bestGender.java 中的 Gender 类完全相同 匿名内部类的原理,创建的是 Gender 的子类实例25.在枚举类里定义抽象方法,为不同枚举值提供不同实现,也是匿名内部类的原理java view plaincopyprint? public enum O
36、peration2 PLUS public double eval(double x , double y) return x + y; , MINUS public double eval(double x , double y) return x - y; , TIMES public double eval(double x , double y) return x * y; , DIVIDE public double eval(double x , double y) return x / y; ; /为枚举类定义一个抽象方法, /这个抽象方法由不同枚举值提供不同的实现 public
37、 abstract double eval(double x, double y); public static void main(String args) System.out.println(Operation2.PLUS.eval(3, 4); System.out.println(Operation2.MINUS.eval(5, 4); System.out.println(Operation2.TIMES.eval(5, 4); System.out.println(Operation2.DIVIDE.eval(5, 4); 6.9 垃圾回收机制回收对象前,会先调用它的 finalize 方法,该方法可能使该对象重新复活。不要主动调用某个对象的 finalize 方法;finalize 方法何时被调用是否被调用具有不确定性,不一定会执行;finalize 方法出现异常时,垃圾回收机制不会报告异常;finalize 方法可能使该对象或系统中的其他对象重新可达。七、与运行环境交互1.Scanner 类是一个基于正则表达式的文本扫描器;System 类和