全部博文(842)
分类: Java
2012-05-07 12:29:57
1. 局部变量不能被static、private、protected、public等修饰符修饰。不能通过类名或引用变量名来访问局部变量。
2. 只能在构造方法或实例方法内使用this关键字,而在静态方法和静态代码块内不能使用this关键字。
3. Java虚拟机会自动初始化类的成员变量,但是局部变量必须被显示初始化。
4. ==比较的是地址值。equals()比较的是内容。
5. String的内容不能改变,stringBuffer的内容可以改变。String可以直接赋值初始化,StringBuffer必须通过构造函数初始化。String通过+进行字符串连接。StringBuffer通过append()方法进行字符串连接。
6. 操作符”>>”进行算术右移位运算,也称带符号右移位运算。
而操作符”>>>”进行的是逻辑右移位运算。不带符号右移位操作。在移位的过程中,二进制数的开头增加的位都是0.
7. java浮点类型数据 有两个特殊的值:负无穷大(-Infinity)和正无穷大(Infinity)。
8. 浮点数不支持位运算。如对double类型的数据进行”>>”或”<<”是不合法的。
9. 运算符 && 与 || 具有短路功能。当前半部分能判定结果时不会对后半部分进行操作。
10. & | 没有短路功能。
11. 在switch(expr)语句中,expr表达式的类型必须是与int类型兼容的基本类型。所谓与int类型兼容就是指自动转换为int类型。因此expr表达式的合法类型包括byte、short、char和int类型。Long类型和浮点类型不能自动转为int类型,因此不能作为expr表达式的类型。在“case value”子句中,value的类型必须是与int类型兼容的基本类型,包括:byte、short、char和int类型。Value必须是常量。各个case子句的value表达式的值不同。在switch语句中最多只能有一个default子句。default子句是可选的。当switch表达式的值不与任何case子句匹配时,程序执行default子句。假如没有default子句则程序直接退出switch语句。如果switch表达式与某个case表达式匹配或与default情况匹配,就从这个case子句或default子句开始执行,如果遇到break语句就退出整个switch语句,否则依次执行switch语句中后续的case子句,不再检查case表达式的值。
12. 目前Java语言不支持goto语句。Java语言把goto和const作为保留字,意味着目前还未用到它们,在将来的版本中也许会用到它们。
13. continue语句中的标号必须定义在while、do…while和for循环语句前面,不能定义在switch语句的前面。break语句中的标号必须定义在while、do…while和for循环语句或switch语句前面。break语句标号将退出语句标号所在的循环。故break语句标号提供了退出多重循环的功能。
14. java中继承关键字是extends。public class Sub extends Base{}分两种情况:当Sub和Base类位于同一个包中时,Sub类继承Base类中public、protected和默认访问级别的成员变量和成员方法。当Sub类 和Base类位于不同包中时Sub类继承Base类中public和protected访问级别的成员变量和成员方法。Java语言不支持多继承。一个类只能直接继承一个类。尽管一个类只能有一个直接的父类,但是它可以有多个间接的父类。如:class Base1 extends Base2{……} class Sub extends Base1{……}。所有的java类都直接或间接地继承了java.lang.Object类。
15. 重载方法必须满足以下条件:
方法名相同。
方法的参数类型、个数、顺序至少有一项不同。
方法的返回类型可以不相同。
方法的修饰符可以不相同。
16. 在一个类中不允许定义两个方法名相同并且参数签名也完全相同的方法。因为若存在则java虚拟机在运行时无法决定到底执行哪个方法。参数签名是指参数的类型、个数和顺序。
17. 子类方法不能缩小父类方法的访问权限。例如父类中方法是public修饰的,而子类中覆盖的方法是private,那这是无效的方法覆盖,将导致编译错误。子类方法不能抛出比父类方法更多的异常。子类方法抛出的异常必须和父类方法抛出的异常相同或者子类方法抛出的异常类是父类方法抛出的异常类的子类。
18. 方法覆盖只存在于子类和父类(包括直接父类和间接父类)之间。在同一个类中方法只能被重载,不能被覆盖。父类的静态方法不能被子类覆盖为非静态方法。
19. 子类可以定义与父类的静态方法同名的静态方法,以便在子类中隐藏父类的静态方法。在编译时,子类定义的静态方法也必须满足与方法覆盖类似的约束:方法的参数签名一致,返回类型一致,不能缩小父类方法的访问权限,不能抛出更多的异常。
20. 子类隐藏父类的静态方法和子类覆盖父类的实例方法,这两者的区别在于:运行时,java虚拟机把静态方法和所属的类绑定,而把实例方法和所属的实例绑定。如method()是实例方法,被子类覆盖了,staticMethod()是静态方法。那么Base base1=new Sub();
Base1.method()将调用子类Sub中的method方法。此时父类Base中的实例方法method()被子类覆盖。而base1.staticMethod()将调用Base类的staticMethod()方法。可见父类Base的静态方法staticMethod()不能被子类覆盖。而Sub sub1=new Sub(); sub1.staticMethod()将调用子类Sub的staticMethod()方法。Base类的staticMethod()方法被Sub类的staticMethod()方法隐藏。
另外,父类的非静态方法不能被子类覆盖为静态方法。
父类的私有方法不能被子类覆盖。
父类的抽象方法可以被子类通过两种途径覆盖:一是子类实现父类的抽象方法,二是子类重新声明父类的抽象方法。
父类的非抽象方法可以被覆盖为抽象方
21. 方法覆盖和方法重载具有以下相同点:
都要求方法名相同。
都可以用于抽象方法和非抽象方法之间。
方法覆盖和方法重载具有以下不同点:
方法覆盖要求参数签名必须一致,而方法重载要求参数签名必须不一致。
方法覆盖要求返回类型必须一致,而方法重载对此不做限制。
方法覆盖只能用于子类覆盖父类的方法。方法重载用于同一个类的所有方法。
方法覆盖对方法的访问权限和抛出的异常有特殊的要求,而方法重载在这方面没有任何限制。
父类的一个方法只能被子类覆盖一次,而一个方法在所在的类中可以被重载多次。
22. 只能在构造方法或实例方法内使用super关键字。而在静态方法和静态代码块内不能使用super关键字。
23. Java编译器允许在具有直接或间接继承关系的类之间进行类型转换。对于向上转型,不必使用强制类型转换。因为子类的对象肯定也可看做父类的对象。对于向下转型,必须进行强制类型转换。若两个类之间没有继承关系则不允许进行类型转换。
24. 实例方法与引用变量实际引用的对象的方法绑定属于动态绑定。静态方法与引用变量所声明的类型的方法绑定属于静态绑定。成员变量(包括静态变量和实例变量)与引用变量所声明的类型的成员变量绑定属于静态绑定。
25. 当一个系统使用一颗继承树上的类时,应该尽可能地把引用变量声明为继承树的上层类型,这可以提高两个系统之间的松耦合。如果继承树上有接口类型,那么应该尽可能地把引用变量声明为继承树上层的接口类型。在设计继承树时,首先进行自下而上的抽象,即识别子类之间所拥有的共同属性和功能,然后抽象出共同的父类,位于继承树最上层的父类描述系统对外提供哪些服务。
26. 父类的构造方法不允许调用可被子类覆盖的方法。
27. 组合关系和继承关系相比,前者的最主要优势是不会破坏封装,当类A与类C之间为组合关系时,类C封装实现,仅向类A提供接口;而当类A与类C之间为继承关系时,类C会向类A暴露部分实现细节。在软件开发阶段,组合关系虽然不会比继承关系减少编码量,但是到了软件维护阶段,由于组合关系使系统具有较好的松耦合性,因此使得系统更加容易维护。组合关系的缺点是比继承关系要创建更多的对象。组合关系使系统具有更好的可扩展性。继承关系是静态的,在运行时,子类无法改变它的父类。而组合关系是允许动态变化的,这使得整体类在运行时可以灵活地改变实现方式。
28. 继承关系最大的弱点是打破了封装,子类能够访问父类的实现细节,子类与父类之间紧密耦合,子类缺乏独立性,从而影响了子类的可维护性。为了尽可能地克服继承的这一缺陷,应该遵循以下原则:
精心设计专门用于被继承的类,继承树的抽象层应该比较稳定。
对于父类中不允许覆盖的方法,采用final修饰符来禁止其被子类覆盖。
对于不是专门用于被继承的类,禁止其被继承。
优先考虑组合关系来提高代码的可重用性。
组合关系 |
继承关系 |
优点:不破坏封装,整体类与局部类之间松耦合,彼此相对独立 |
缺点:破坏封装,子类与父类之间紧密耦合,子类依赖于父类的实现,子类缺乏独立性。 |
优点:具有较好的可扩展性 |
缺点:支持扩展,但是往往以增加系统结构的复杂度为代价 |
优点:支持动态组合。在运行时,整体对象可以选择不同类型的局部对象。 |
缺点:不支持动态继承。在运行时,子类无法选择不同的父类 |
缺点:整体类不能自动获得和局部类同样的接口。 |
优点:子类能自动继承父类的接口 |
缺点:创建整体类的对象时,需要创建所有局部类的对象 |
优点:创建子类的对象时,无须创建父类的对象。 |
优点:整体类可以对局部类进行包装,封装局部类的接口,提供新的接口。 |
缺点:子类不能改变父类的接口。 |
29. 修饰顶层类的修饰符包括abstract、public和final。而static、protected和private不能修饰顶层类。局部变量只能用final修饰。修饰成员方法可以用abstract、static、public、protected、private、synchronized(同步的)、native(本地的)、final。修饰构造方法可以用public、protected、private。修饰成员变量可以用static、public、protected、private、transient(暂时的)、volatile(易失的)、final。修饰局部变量只能用final。
30. 访问控制分4中级别。
公开级别:用public修饰,对外公开。
受保护级别:用protected修饰,向子类及同一个包中的类公开。
默认级别:没有访问控制修饰符,向同一个包中的类公开。
私有级别:用private修饰,只有类本身可以访问,不对方公开。
顶层类只可以处于公开或默认访问级别,因此顶层类不能用private和protected修饰。否则导致编译错误。
31. 抽象类中可以没有抽象方法。但包含了抽象方法的类必须被定义为抽象类。若子类没有实现父类中的所有抽象方法,则子类必须被定义为抽象类,否则编译出错。没有抽象构造方法,也没有抽象静态方法。Static和abstract修饰符不能连用。抽象类中可以有非抽象的构造方法,创建子类的实例时可能会调用这些构造方法。抽象类不能被实例化,然而可以创建一个引用变量,其类型是一个抽象类,并让它引用非抽象的子类的一个实例。抽象类及抽象方法不能被final修饰符修饰。abstract修饰符与final修饰符不能连用。
32. 用final修饰的类不能被继承,没有子类。用final修饰的方法不能被子类的方法覆盖。用final修饰的变量表示常量,只能被赋一次值。Final不能用来修饰构造方法。父类中用private修饰的方法不能被子类覆盖,因此private类型的方法默认是final类型的。Final变量都必须显式初始化。Final修饰符可以修饰静态变量、实例变量和局部变量。
33. 对于final类型的实例变量,可以在定义变量时初始化也可以在构造方法中初始化。对于final类型的静态变量,只能在定义变量时初始化。如果将引用类型的变量用final修饰,那么该变量只能始终引用一个对象,但可以改变对象的内容。
34. P224