资源描述
Java学习笔记
JASE SE知识复习
1. 类是一种抽象的概念,对象是类的一种具体表示形式,是具体的概念。先有类,然后由类来生成对象(Object )。对象又 叫做实例(Instance)。
2. 类由两大部分构成:属性以及方法。属性一般用名词来表示, 方法一般用动词来表示。 3. 如果一个java源文件中定义了多个类,那么这些类中最多只能有一个类是public 的,换句话说,定义的多个类可以都不是public 的。
4. 在Java中进行方法的参数传递时,无论传递的是原生数据类型还是引用类型,参数传递方式统一是传值(pass by value )。 Java 中没有传引用(pass by reference)的概念。
5. 方法重载 (Overload)。表示两个或多个方法名字相同,但方法参数不同。方法参数不同有两层含义:
1)参数个数不同。
2)参数类型不同。
注意:方法的返回值对重载没有任何影响。
6. 构造方法重载:只需看参数即可。如果想在一个构造方法中调用另外一个构造方法,那么可以使用this()的方式调用,this()括号中的参数表示目标构造方法的参数。this()必须要作为构造方法的第一条语句,换句话说,this()之前不能有任何可执行的代码。
7. 继承(Inheritence):Java是单继承的,意味着一个类只能从另一个类继承(被继承的类叫做父类【基类,base class】,继承的类叫做子类),Java中的继承使用extends 关键字。
8. 当生成子类对象时,Java 默认首先调用父类的不带参数的构造方法,然后执行该构造方法,生成父类的对象。接下来,再去调用子类的构造方法,生成子类的对象。【要想生成子类的对象,首先需要生成父类的对象,没有父类对象就没有子类对象。比如说:没有父亲,就没有孩子】。
9. super 关键字:super 表示对父类对象的引用。
10.如果子类使用super()显式调用父类的某个构造方法,那么在执行的时候就会寻找与 super()所对应的构造方法而不会再去寻找父类的不带参数的构造方法。与this 一样,super 也必须要作为构造方法的第一条执行语句,前面不能有其他可执行语句。
11.关于继承的3 点:
a) 父类有的,子类也有
b) 父类没有的,子类可以增加
c) 父类有的,子类可以改变
12.关于继承的注意事项
a) 构造方法不能被继承
b) 方法和属性可以被继承
c) 子类的构造方法隐式地调用父类的不带参数的构造方法
d) 当父类没有不带参数的构造方法时,子类需要使用super 来显式地调用父类的构造方法,super 指的是对父类的引用
e) super 关键字必须是构造方法中的第一行语句。
13.方法重写(Override):又叫做覆写,子类与父类的方法返回类型一样、方法名称一样,参数一样,这样我们说子类与父类的方法构成了重写关系。
14.方法重写与方法重载之间的关系:重载发生在同一个类内部的两个或多个方法。重写发生在父类与子类之间。
15. 当两个方法形成重写关系时,可以在子类方法中通super.run()形式调用父类的run()方法,其中super.run()不必放在第一行语句,因此此时父类对象已经构造完毕,先调用父类的run()方法还是先调用子类的run()方法是根据程序的逻辑决定的。
16.在定义一个类的时候,如果没有显式指定该类的父类,那么该类就会继承于java.lang.Object 类(JDK 提供的一个类,Object 类是Java 中所有类的直接或间接父类)。
17. 多态(Polymorphism):我们说子类就是父类(玫瑰是花,男人是人),因此多态的意思就是:父类型的引用可以指向子类的对象。
1.多态:父类型的引用可以指向子类型的对象。
2. Parent p = new Child();当使用多态方式调用方法时,首先检查父类中是否有sing()方法,如果没有则编译错误;如果有,再去调用子类的sing()方法。
3. 一共有两种类型的强制类型转换:
a) 向上类型转换(upcast):比如说将Cat 类型转换为Animal 类型,即将子类型转换为父类型。对于向上类型转换,不需要显式指定。
b) 向下类型转换(downcast):比如将Animal 类型转换为Cat 类型。即将父类型转换为子类型。对于向下类型转换,必须要显式指定 (必须要使用强制类型转换)。
4. 抽象类(abstract class):使用了abstract 关键字所修饰的类叫做抽象类。抽象类无法实例化,也就是说,不能new 出来一个抽象类的对象(实例)。
5. 抽象方法(abstract method ):使用abstract 关键字所修饰的方法叫做抽象方法。抽象方法需要定义在抽象类中。相对于抽象方法,之前所定义的方法叫做具体方法(有声明,有实现)。
6. 如果一个类包含了抽象方法,那么这个类一定是抽象类。
7. 如果某个类是抽象类,那么该类可以包含具体方法(有声明、有实现)。
8. 如果一个类中包含了抽象方法,那么这个类一定要声明成abstract class,也 就是说,该类一定是抽象类;反之,如果某个类是抽象类,那么该类既可以包含抽象方法,也可以包含具体方法。
9. 无论何种情况,只要一个类是抽象类,那么这个类就无法实例化。
10. 在子类继承父类(父类是个抽象类)的情况下,那么该子类必须要实现父类中所定义的所有抽象方法;否则,该子类需要声明成一个abstract class。
11. 接口(interface):接口的地位等同于 class,接口中的所有方法都是抽象方法。在声明接口中的方法时,可以使用abstract 关键字,也可以不使用。通常情况下,都会省略掉abstract 关键字。
12. 可以将接口看作是特殊的抽象类(抽象类中可以有具体方法,也可以有抽象方法,而接口中只能有抽象方法,不能有具体方法)。
13. 类可以实现接口。实现使用关键字implements 表示,代表了某个类实现了某个接口。
14. 一个类实现了某个接口,那么该类必须要实现接口中声明的所有方法。如果该类是个抽象类,那么就无需实现接口中的方法了。
15. Java 是单继承的,也就是说某个类只能有唯一一个父类;一个类可以实现多个接口,多个接口之间使用逗号分隔。
16. 多态:所谓多态,就是父类型的引用可以指向子类型的对象,或者接口类型的引用可以指向实现该接口的类的实例。关于接口与实现接口的类之间的强制类型转换方式与父类和子类之间的强制类型转换方式完全一样。
17. static 关键字:可以用于修饰属性,也可以用于修饰方法,还可以用于修饰类(后面的课程讲)
18. static 修饰属性:无论一个类生成了多少个对象,所有这些对象共同使用唯一一份静态的成员变量;一个对象对该静态成员变量进行了修改,其他对象的该静态成员变量的值也会随之发生变化。如果一个成员变量是static的,那么我们可以通过类名.成员变量名的方式来使用它(推荐使用这种方式)。
19. static 修饰方法:static 修饰的方法叫做静态方法。对于静态方法来说,可以使用类名.方法名的方式来访问。
20. 静态方法只能继承,不能重写(Override)。
21. final 关键字:final 可以修饰属性、方法、类。
22. final 修饰类:当一个类被final 所修饰时,表示该类是一个终态类,即不能被继承。
23. final 修饰方法:当一个方法被final 所修饰时,表示该方法是一个终态方法,即不能被重写(Override)。
24. final 修饰属性:当一个属性被final 所修饰时,表示该属性不能被改写。
25. 当final 修饰一个原生数据类型时,表示该原生数据类型的值不能发生变化(比如说不能从10 变为20);如果final 修饰一个引用类型时,表示该引用类型不能再指向其他对象了,但该引用所指向的对象的内容是可以发生变化的。
26. 对于final 类型成员变量,一般来说有两种赋初值方式:
a) 在声明final 类型的成员变量时就赋上初值
b) 在声明final 类型的成员变量时不赋初值,但在类的所有构造方法中都为其赋上初值。
27. static 代码块:静态代码块。静态代码块的作用也是完成一些初始化工作。首先执行静态代码块,然后执行构造方法。静态代码块在类被加载的时候执行,而构造方法是在生成对象的时候执行;要想调用某个类来生成对象,首先需要将类加载到Java 虚拟机上(JVM ),然后由JVM 加载这个类来生成对象。
28. 类的静态代码块只会执行一次,是在类被加载的时候执行的,因为每个类只会被加载一次,所以静态代码块也只会被执行一次;而构造方法则不然,每次生成一个对象的时候都会调用类的构造方法,所以new 一次就会调用构造方法一次。
29. 如果继承体系中既有构造方法,又有静态代码块,那么首先执行最顶层的类的静态代码块,一直执行到最底层类的静态代码块,然后再去执行最顶层类的构造方法,一直执行到最底层类的构造方法。注意:静态代码块只会执行 一次。
30. 不能在静态方法中访问非静态成员变量;可以在静态方法中访问静态的成员 变量。可以在非静态方法中访问静态的成员变量。
31. 总结:静态的只能访问静态的;非静态的可以访问一切。
32. 不能在静态方法中使用this 关键字。
1. 接口中所声明的方法都是抽象方法。接口中的方法都是public 的。
2. 接口中也可以定义成员变量。接口中的成员变量都是public、final、static 的。
3. 一个类不能既是final,又是abstract 的。因为abstract 的主要目的是定义一种约定,让子类去实现这种约定,而final 表示该类不能被继承,这样abstract 希望该类可以被继承而final 明确说明该类不能被继承,两者矛盾。因此一个类不能既是final 的,
又是abstract 的。
4. Design Pattern (设计模式)。单例模式(Singleton):表示一个类只会生成唯一的一个对象。
5. 包(package)。用于将完成不同功能的类分门别类,放在不同的目录(包)下。包的命名规则:将公司域名反转作为包名。,com.shengsiyuan (包名),对于包名:每个字母都需要小写。如果定义类的时候没有使用package,那么Java 就认为我们所定义的类位于默认包里面(default package)。
6. 编译带有package 声明的Java 源文件有两种方式:
a) 直接编译,然后根据类中所定义的包名,逐一手工建立目录结构,最后将生成的class文件放到该目录结构中(很少使用,比较麻烦)。
b) 使用编译参数–d,方式为javac –d .源文件.java,这样在编译后,编译器会自动帮助我们建立好包所对应的目录结构。
7. 有两个包名,分别是aa.bb.cc 与aa.bb.cc.dd,那么我们称后者为前者的子包。
8. 导入(import),将使用package 分离的各个类导入回来,让编译器能够找到所需要的类。
9. import 的语法:import com.shengsiyuan.PackageTest;
10. import com.shengsiyuan.*,表示导入com.shengsiyuan 包下面的所有类。
11. import aa.bb.*并不会导入aa.bb.cc 包下面的类。这时需要这样写:
import aa.bb.*;
import aa.bb.cc.*;
12. 关于package、import、class 的顺序问题:
a) 首先需要定义包(package),可选
b) 接下来使用import 进行导入,可选
c) 然后才是class 或interface 的定义。
13. 如果两个类在同一个包下面,那么则不需要导入,直接使用即可。
14. 访问修饰符 (access modifier)。
1) public (公共的):被public 所修饰的属性和方法可以被所有类访问。
2) protected (受保护的):被protected 所修饰的属性和方法可以在类内部、相同包以及该类的子类所访问。
3) private(私有的):被private 所修饰的属性和方法只能在该类内部使用
4 ) 默认的(不加任何访问修饰符):在类内部以及相同包下面的类所使用。
15. instanceof:判断某个对象是否是某个类的实例。语法形式:引用名 instanceof 类名(接口名),返回一个boolean 值。
16. People people = new Man();
17. System.out.println(people instanceof People); //结果为true,因为Man 是People 的子类,根据继承,子类就是父类,因此Man 也可以看作是People 的实例。
18. 相等性的比较 (==)
1) 对于原生数据类型来说,比较的是左右两边的值是否相等。
2) 对于引用类型来说,比较左右两边的引用是否指向同一个对象,或者说左右两边的引用地址是否相同。
19. java.lang.Object 类。java.lang 包在使用的时候无需显式导入,编译时由编译器自动帮助我们导入。
20. API (Application Programming Interface ),应用编程接口。
21. 当打印引用时,实际上会打印出引用所指对象的toString()方法的返回值,因为每个类都直接或间接地继承自Object,而Object 类中定义了toString(),因此每个类都有toString()这个方法。
22. 关于进制的表示:16 进制,逢16 进一,16 进制的数字包括:0~9,A,B,C,D,E,F,
23. equals()方法,该方法定义在Object 类当中,因此Java 中的每个类都具有该方法,对于Object 类的equals()方法来说,它是判断调用equals()方法的引用与传进来的引用是否一致,即这两个引用是否指向的是同一个对象。对于Object 类的equals()方法来说,它等价于==。
24. 对于String类的equals()方法来说,它是判断当前字符串与传进来的字符串的内容是否一致。
25. 对于String 对象的相等性判断来说,请使用equals()方法,而不要使用==。
26. String 是常量,其对象一旦创建完毕就无法改变。当使用+拼接字符串时,会生成新的String 对象,而不是向原有的String 对象追加内容。
27. String Pool (字符串池)
28. String s = “aaa”; (采用字面值方式赋值)
1) 查找String Pool 中是否存在“aaa”这个对象,如果不存在,则在String Pool 中创建一个“aaa”对象,然后将String Pool 中的这个“aaa”对象的地址返回来,赋给引用变量s,这样s 会指向String Pool 中的这个“aaa”字符串对象
2) 如果存在,则不创建任何对象,直接将String Pool 中的这个“aaa”对象地址返回来,赋给s 引用。
29. String s = new String(“aaa”);
1) 首先在String Pool 中查找有没有“aaa”这个字符串对象,如果有,则不在String Pool中再去创建“aaa”这个对象了,直接在堆中(heap)中创建一个“aaa”字符串对象,然后将堆中的这个“aaa”对象的地址返回来,赋给s 引用,导致s 指向了堆中创建的这个“aaa”字符串对象。
2) 如果没有,则首先在String Pool 中创建一个“aaa “对象,然后再在堆中(heap)创建一个”aaa “对象,然后将堆中的这个”aaa “对象的地址返回来,赋给s 引用,导致s 指向了堆中所创建的这个”aaa “对象。
1. 包装类(Wrapper Class )。针对于原生数据类型的包装。所有的包装类(8个)位于java.lang包下。Java 中的8 个包装类分别是:Byte, Short, Integer, Long, Float, Double, Character, Boolean。他们的使用方式都是一样的,可以实现原生数据类型与包装类型的双向转换
2.数组(Array ):相同类型数据的集合就叫做数组。
3. 如何定义数组。type[]变量名= new type[数组中元素的个数];可以按照下列方式定义长度为10 的数组:
int[] a = new int[10]; 或者 int a[] = new int[10];
4. 数组中的元素索引是从0 开始的。对于数组来说,最大的索引==数组的长度– 1。
5. 定义数组的第3 种方式:type[]变量名 = {new type[]}{逗号分隔的初始化值列表};
6. Java 中的每个数组都有一个名为length 的属性,表示数组的长度。length 属性是public,final,int 的。数组长度一旦确定,就不能改变大小。
7. int[] a = new int[10],其中a 是一个引用,它指向了生成的数组对象的首地址,数组中每个元素都是int 类型,其中仅存放数据值本身。
8. 二维数组。二维数组是一种平面的二维结构,本质上是数组的数组。二维数组的定义方式:type[][] a = new type[2][3];
9. 三维数组。type[][][] a = new type[2][3][4];
10. 冒泡排序。(掌握交换排序,快速排序的原理与实现方式)
11. 二分查找(Binary Search):待查找的数组要有序。
12. 随机生成50 个数字(整数),每个数字的范围是[10, 50],统计每个数字出现的次数以及出现次数最多的数字与它的个数,最后将每个数字及其出现次数打印出来,如果某个数字出现次数为0,则不要打印它。打印时按照数字的升序排列。
1. 对于Java 中的常量的命名规则:所有单词的字母都是大写,如果有多个单词,那么使用下划线连接即可。比如说:
public static final int AGE_0F_PERSON = 20;
2. 在Java 中声明final 常量时通常都会加上static 关键字,这样对象的每个实例都会访问唯一一份常量值。
3. IDE (Integrated Development Environment),集成开发环境。
1) NetBeans。http://netbeans.org/,最高版本是6.9.1
2) JBuilder 。
3) Intellij IDEA
4) Eclipse (日蚀、月蚀),最高版本3.6.1
4. 集合中存放的依然是对象的引用而不是对象本身。
5. ArrayList 底层采用数组实现,当使用不带参数的构造方法生成ArrayList 对象时,实际上会在底层生成一个长度为10 的Object 类型数组
6. 如果增加的元素个数超过了10 个,那么ArrayList 底层会新生成一个数组,长度为原数组的1.5 倍+1,然后将原数组的内容复制到新数组当中,并且后续增加的内容都会放到新数组当中。当新数组无法容纳增加的元素时,重复该过程。
7. 对于ArrayList 元素的删除操作,需要将被删除元素的后续元素向前移动,代价比较高。
8. 集合当中只能放置对象的引用,无法放置原生数据类型,我们需要使用原生数据类型的包装类才能加入到集合当中。9. 集合当中放置的都是Object 类型,因此取出来的也是Object 类型,那么必须要使用强制类型转换将其转换为真正的类型(放置进去的类型)。
10. 关于ArrayList 与LinkedList 的比较分析
a) ArrayList 底层采用数组实现,LinkedList 底层采用双向链表实现。
b) 当执行插入或者删除操作时,采用LinkedList 比较好。
c) 当执行搜索操作时,采用ArrayList 比较好。
1.当向ArrayList添加一个对象时,实际上就是将该对象放置到了ArrayList底层所维护的数组当中;当向LinkedList中添加一个对象时,实际上LinkedList内部会生成一个Entry 对象,该Entry 对象的结构为:
Entry
{ Entry previous;
Object element;
Entry next; }
其中的Object 类型的元素element 就是我们向LinkedList 中所添加的元素,然后Entry又构造好了向前与向后的引用previous、next,最后将生成的这个Entry 对象加入到了链表当中。换句话说,LinkedList 中所维护的是一个个的Entry 对象。
2. 关于Object 类的equals 方法的特点
a) 自反性:x.equals(x)应该返回true
b) 对称性:x.equals(y)为true,那么y.equals(x)也为true 。
c) 传递性:x.equals(y)为true 并且y.equals(z)为true,那么x.equals(z)也应该为true 。
d) 一致性:x.equals(y)的第一次调用为true,那么x.equals(y)的第二次、第三次、第n次调用也应该为true,前提条件是在比较之间没有修改x 也没有修改y。
e) 对于非空引用x,x.equals(null)返回false 。
3. 关于Object 类的hashCode()方法的特点:
a) 在Java 应用的一次执行过程当中,对于同一个对象的hashCode 方法的多次调用,他们应该返回同样的值 (前提是该对象的信息没有发生变化)。
b) 对于两个对象来说,如果使用equals 方法比较返回true,那么这两个对象的hashCode值一定是相同的。
c) 对于两个对象来说,如果使用equals 方法比较返回false,那么这两个对象的hashCode值不要求一定不同 (可以相同,可以不同),但是如果不同则可以提高应用的性能。
d) 对于Object类来说,不同的Object 对象的hashCode值是不同的(Object 类的hashCode值表示的是对象的地址)。
4. 当使用HashSet 时,hashCode()方法就会得到调用,判断已经存储在集合中的对象的hash code 值是否与增加的对象的hashcode 值一致;如果不一致,直接加进去;如果一致,再进行equals 方法的比较,equals 方法如果返回true,表示对象已经加进去了,就不会再增加新的对象,否则加进去。
5. 如果我们重写equals 方法,那么也要重写hashCode 方法,反之亦然。
6. Map (映射):Map 的keySet()方法会返回key 的集合,因为Map 的键是不能重复的,因此keySet()方法的返回类型是Set;而Map 的值是可以重复的,因此values()方法的返回类型是Collection,可以容纳重复的元素。
注:HashMap是异步处理机制,而Hashtable是同步的;
1. 有这样一个类:
public class Person
{
Private int id;
Private String name;
Private int age;
}
// getter and setter
要求:假如有若干个类Person 对象存在一个List 当中,对他们进行排序,分别按照名字、年龄、id 进行排序 (要有正序与倒序两种排序方式)。假如年龄或者姓名重复,按照id的正序进行排序。要求使用策略模式进行。
2. HashSet 底层是使用HashMap 实现的。当使用add 方法将对象添加到Set 当中时,实际上是将该对象作为底层所维护的Map 对象的key,而value 则都是同一个Object对象(该对象我们用不上);
3. HashMap 底层维护一个数组,我们向HashMap 中所放置的对象实际上是存储在该数组当中;
4. 当向HashMap 中put 一对键值时,它会根据key 的hashCode 值计算出一个位置,该位置就是此对象准备往数组中存放的位置。
5. 如果该位置没有对象存在,就将此对象直接放进数组当中;如果该位置已经有对象存在了,则顺着此存在的对象的链开始寻找(Entry 类有一个Entry 类型的next 成员变量,指向了该对象的下一个对象),如果此链上有对象的话,再去使用equals方法进行比较,如果对此链上的某个对象的equals 方法比较为false,则将该对象放到数组当中,然后将数组中该位置以前存在的那个对象链接到此对象的后面。
6. HashMap 的内存实现布局:
7. 所谓泛型:就是变量类型的参数化。
1. 当遍历集合或数组时,如果需要访问集合或数组的下标,那么最好使用旧式的方式来实现循环或遍历,而不要使用增强的for 循环,因为它丢失了下标信息。
2. Integer 类有一个缓存,它会缓存介于-128~127 之间的整数。
3. 可变参数:可变参数本质上就是一个数组,对于某个声明了可变参数的方法来说,我们既可以传递离散的值,也可以传递数组对象。但如果将方法中的参数定义为数组,那么只能传递数组对象而不能传递离散的值。
4. 可变参数必须要作为方法参数的最后一个参数,即一个方法不可能具有两个或两个以上的可变参数。
5. 枚举(Enum):我们所定义的每个枚举类型都继承自java.lang.Enum 类,枚举中的每个成员默认都是public static final 的。
6. 而每个枚举的成员其实就是您定义的枚举类型的一個实例(Instance)。换句话说,当定义了一个枚举类型后,在编译时刻就能确定该枚举类型有几个实例,分别是什么。在运行期间我们无法再使用该枚举类型创建新的实例了,这些实例在编译期间就已经完全确定下来了。
7. 静态导入:
a) import static mon.Common.Age;
b) import static mon.Common.output;
8. 表示导入Common 类中的静态成员变量AGE 以及静态方法output。注意:使用import static 时,要一直导入到类中的静态成员变量或静态方法。
9. Java 中,无论生成某个类的多少个对象,这些对象都会对应于同一个Class 对象。
1. 要想使用反射,首先需要获得待处理类或对象所对应的Class对象。
2. 获取某个类或某个对象所对应的Class 对象的常用的3 种方式:
a)使用Class类的静态方法forName:Class.forName(“java.lang.String”);
b) 使用类的.class 语法:String.class;
c) 使用对象的getClass()方法:String s = “aa”; Class<?> clazz = s.getClass();
3. 若想通过类的不带参数的构造方法来生成对象,我们有两种方式:
a) 先获得Class 对象,然后通过该Class 对象的newInstance()方法直接生成即可:
Class<?> classType = String.class;
Object obj = classType.newInstance();
b) 先获得Class 对象,然后通过该对象获得对应的Constructor 对象,再通过该Constructor对象的newInstance()方法生成:
Class<?> classType = Customer.class;
Constructor cons = classType.getConstructor(new Class[]{}); Object obj = cons.newInstance(new Object[]{});
4. 若想通过类的带参数的构造方法生成对象,只能使用下面这一种方式:
Class<?> classType = Customer.class;
Constructor cons = classType.getConstructor(new Class[]{String.class, int.class});
Object obj = cons.newInstance(new Object[]{“hello”, 3});
5. Integer.TYPE 返回的是int,而Integer.class 返回的是Integer 类所对应的Class 对象。
1. 静态代理模式图示
2. Java 注解(Annotation ):
a) Override 注解表示子类要重写(override)父类的对应方法。
b) Deprecated 注解表示方法是不建议被使用的。
c) SuppressWarnings 注解表示抑制警告。
3. 自定义注解:当注解中的属性名为value时,在对其赋值时可以不指定属性的名称而直接写上属性值即可;除了value 以外的其他值都需要使用name=value 这种赋值方式,即明确指定给谁赋值。
4.当我们使用@interface关键字定义一个注解时,该注解隐含地继承了 java.lang.annotation.Annotation 接口;如果我们定义了一个接口,并且让该接口继承自Annotation,那么我们所定义的接口依然还是接口而不是注解;Annotation本身是接口而不是注解。可以与Enum 类比。
5. JUnit (3.8、4.x ):Keep the bar green to keep the code clean.
6. 我的名言:没有反射,很多框架就不存在了。(No Reflection,No most frameworks)。
7. JUnit4 的执行的一般流程:
a) 首先获得待测试类所对应的Class 对象。
b) 然后通过该Class 对象获得当前类中所有public 方法所对应的Method 数组。
c) 遍历该Method 数组,取得每一个Method 对象
d) 调用每个Method 对象的isAnnotationPresent(Test.class)方法,判断该方法是否被Test注解所修饰。
e) 如果该方法返回true,那么调用method.invoke()方法去执行该方法,否则不执行。
8. 单元测试不是为了证明你是对的,而是证明你没有错误。
9. Writing Secure Code (编写安全的代码):Input is evil。
10. 异常(Exception)。
11. Java 中的异常分为两大类:
a) Checked exception (非 Runtime Exception)
b) Unchecked exception (Runtime Exception)
12. Java中所有的异常类都会直接或间接地继承自Exception。
13. RuntimeException 类也是直接继承自Exception 类,它叫做运行时异常,Java中所有的运行时异常都会直接或间接地继承自RuntimeException。
14. Java中凡是继承自Exception 而不是继承自RuntimeException的类都是非运行时异常。
15. 异常处理的一般结构是:
try
{
}
catch(Exception e)
{
}
finally
{
}
无论程序是否出现异常,finally 块中的代码都是会被执行的。
16. 对于非运行时异常(checked exception),必须要对其进行处理,处理方式有两种:
第一种是使用try.. catch…finally 进行捕获;第二种是在调用该会产生异常的方法所在的方法声明throws Exception
17. 对于运行时异常(runtime exception),我们可以不对其进行处理,也可以对其进行处理。推荐不对其进行处理。
18. NullPointerException 是空指针异常,出现该异常的原因在于某个引用为null,但你却调用了它的某个方法。这时就会出现该异常。
1. 所谓自定义异常,通常就是定义了一个继承自Exception 类的子类,那么这个类就是一个自定义异常类。通常情况下,我们都会直接继承自Exception 类,一般不会继承某个运行时的异常类。
2. 我们可以使用多个catch 块来捕获异常,这时需要将父类型的catch 块放到子类型的catch 块之后,这样才能保证后续的catch 可能被执行,否则子类型的catch 将永远无法到达,Java编译器会报编译错误;如果多个 catch块的异常类型是独立的(MyException, MyException2),那么谁前谁后都是可以的。
3. 如果try 块中存在return 语句,那么首先也需要将finally 块中的代码执行完毕,然后方法再返回。
4. 如果try块中存在 System.exit(0)语句,那么就不会执行 finally 块中的代码,因为System.exit(0)会终止当前运行的Java 虚拟机,程序会在虚拟机终止前结束执行。
5. GUI (Graphical User Interface),图形用户界面。
6. AWT (Abstract Window Toolkit ),抽象窗口工具集,第一代的Java GUI 组件,是重量级的。
7. Swing,不依赖于底层细节,轻量级的组件。
1. 内部类(Inner Class),内部类共分为4 种。
2. 静态内部类(static inner class):只能访问外部类的静态成员变量与静态方法,生成静态内部类对象的方式为:
OuterClass.InnerClass inner = new OuterClass.InnerClass();
3. 成员内部类(member inner class):可以访问外部类的
展开阅读全文