final实例域
构建对象时必须初始化这样的域(只能初始化一次),并且初始化之后就不能被修改。
特别的,当final修饰的不是基本数据类型,修饰的是一个引用类型,那么就表示该引用值不能变,但其对象本身是可以被修改的。
- 显示初始化;
- 没有显示初始化,就要在构造器或者构造代码块中进行初始化。
注意:将一个类声明为final,只有其中的方法自动成为final,而不包括域。
动态绑定
至此,编译器已经获得需要调用的方法名字和参数类型。
在覆盖一个方法时,子类方法不能低于超类方法的可见性。
例如:方法参数是一个接口类型,在程序运行期间,虚拟机会根据传入的具体的对象,来调用某一个类方法。
抽象类:
- 类即使不含有抽象方法,也可以将其声明为抽象类。
- 抽象类不能被实例化。
- 可以定义一个抽象类的对象变量。
Object:所有类的超类
Object类:
public boolean equals(Object obj) {
return (this == obj);
}
String类:
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String) anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
Objects类:
public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
}
注意:equals方法的参数是Object,不是其他具体类型!
equals相等,则hashCode也相等。
equals和hashCode应用
反射
一、Class类
类类型
Object类中的getClass()方法将会返回一个Class类型的实例。
这个方法只有在className是类名或接口名时才能执行,否则,将会抛出checked exception(已检查异常),需要有异常处理器(try..catch..)。
二、利用反射分析类的能力
package reflection;
import java.util.*;
import java.lang.reflect.*;
/**
* This program uses reflection to print all features of a class.
* @version 1.1 2004-02-21
* @author Cay Horstmann
*/
public class ReflectionTest
{
public static void main(String[] args)
{
// read class name from command line args or user input
String name;
if (args.length > 0) name = args[0];
else
{
Scanner in = new Scanner(System.in);
System.out.println("Enter class name (e.g. java.util.Date): ");
name = in.next();
}
try
{
// print class name and superclass name (if != Object)
Class cl = Class.forName(name);
Class supercl = cl.getSuperclass();
String modifiers = Modifier.toString(cl.getModifiers());
if (modifiers.length() > 0) System.out.print(modifiers + " ");
System.out.print("class " + name);
if (supercl != null && supercl != Object.class) System.out.print(" extends "
+ supercl.getName());
System.out.print("\n{\n");
printConstructors(cl);
System.out.println();
printMethods(cl);
System.out.println();
printFields(cl);
System.out.println("}");
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
System.exit(0);
}
/**
* Prints all constructors of a class
* @param cl a class
*/
public static void printConstructors(Class cl)
{
Constructor[] constructors = cl.getDeclaredConstructors();
for (Constructor c : constructors)
{
String name = c.getName();
System.out.print(" ");
String modifiers = Modifier.toString(c.getModifiers());
if (modifiers.length() > 0) System.out.print(modifiers + " ");
System.out.print(name + "(");
// print parameter types
Class[] paramTypes = c.getParameterTypes();
for (int j = 0; j < paramTypes.length; j++)
{
if (j > 0) System.out.print(", ");
System.out.print(paramTypes[j].getName());
}
System.out.println(");");
}
}
/**
* Prints all methods of a class
* @param cl a class
*/