RefFieldMethodDetails,通过反射机制查看类的域和方法(包括编译器添加的“桥方法”)
public class RefFieldMethodDetails {
/**
* 打印出指定类的
* 1、声明的所有构造方法(包括私有)
* 2、声明的所有方法(包括私有)
* 3、声明的所有域(包括私有)
*/
public static <T> void details(Class<T> clazz){
details(clazz.getName());
}
/**
* 打印出指定类的
* 1、所有公共构造方法(包括超类)
* 2、所有公共方法(包括超类)
* 3、所有公共域(包括超类)
*/
public static <T> void details2(Class<T> clazz){
details2(clazz.getName());
}
/**
* 打印出指定类的
* 1、声明的所有构造方法(包括私有)
* 2、声明的所有方法(包括私有)
* 3、声明的所有域(包括私有)
*/
public static void details(String name){
try {
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) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 打印出指定类的
* 1、所有公共构造方法(包括超类)
* 2、所有公共方法(包括超类)
* 3、所有公共域(包括超类)
*/
public static void details2(String name){
try {
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");
printConstructors2(cl);
System.out.println();
printMethods2(cl);
System.out.println();
printFields2(cl);
System.out.println("}");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//返回本类声明的所有域(包括私有)
private static void printFields(Class cl) {
Field[] fields = cl.getDeclaredFields();
for(Field field : fields){
String modifier = Modifier.toString(field.getModifiers());
Class type = field.getType();
String name = field.getName();
System.out.print(" ");
System.out.print(modifier +" ");
System.out.print(type + " ");
System.out.println(name + ";");
}
}
//返回本类的所有公共域(包括超类)
private static void printFields2(Class cl) {
Field[] fields = cl.getFields();
for(Field field : fields){
String modifier = Modifier.toString(field.getModifiers());
Class type = field.getType();
String name = field.getName();
System.out.print(" ");
System.out.print(modifier +" ");
System.out.print(type + " ");
System.out.println(name + ";");
}
}
//返回本类声明的所有方法(包括私有)
private static void printMethods(Class cl) {
Method[] methods = cl.getDeclaredMethods();
for(Method method : methods){
String modifier = Modifier.toString(method.getModifiers());
Class returnType = method.getReturnType();
String name = method.getName();
Class[] params = method.getParameterTypes();
System.out.print(" ");
if(modifier.length()>0){
System.out.print(modifier + " ");
}
System.out.print(returnType.getSimpleName() +" ");
System.out.print(name+"( ");
for(int i=0;i<params.length;i++){
System.out.print(params[i].getName());
if(i!=params.length-1){
System.out.print(", ");
}
}
System.out.println(" );");
}
}
//返回本类的所有公共方法(包括超类)
private static void printMethods2(Class cl) {
Method[] methods = cl.getMethods();
for(Method method : methods){
String modifier = Modifier.toString(method.getModifiers());
Class returnType = method.getReturnType();
String name = method.getName();
Class[] params = method.getParameterTypes();
System.out.print(" ");
if(modifier.length()>0){
System.out.print(modifier + " ");
}
System.out.print(returnType.getSimpleName() +" ");
System.out.print(name+"( ");
for(int i=0;i<params.length;i++){
System.out.print(params[i].getName());
if(i!=params.length-1){
System.out.print(", ");
}
}
System.out.println(" );");
}
}
//返回本类声明的所有构造方法(包括私有)
private static void printConstructors(Class cl) {
Constructor[] cs = cl.getDeclaredConstructors();
for(Constructor c : cs){
String modifier = Modifier.toString(c.getModifiers());
String name = c.getName();
Class[] params = c.getParameterTypes();
System.out.print(" ");
if(modifier.length()>0){
System.out.print(modifier + " ");
}
System.out.print(name);
System.out.print("( ");
for(int i=0 ;i<params.length ;i++){
System.out.print(params[i].getName());
if(i!=params.length-1){
System.out.print(", ");
}
}
System.out.println(" );");
}
}
//返回本类的所有公共构造方法(包括超类)
private static void printConstructors2(Class cl) {
Constructor[] cs = cl.getConstructors();
for(Constructor c : cs){
String modifier = Modifier.toString(c.getModifiers());
String name = c.getName();
Class[] params = c.getParameterTypes();
System.out.print(" ");
if(modifier.length()>0){
System.out.print(modifier + " ");
}
System.out.print(name);
System.out.print("( ");
for(int i=0 ;i<params.length ;i++){
System.out.print(params[i].getName());
if(i!=params.length-1){
System.out.print(", ");
}
}
System.out.println(" );");
}
}
}
对程序员来说,方法的签名只包括:
1、方法的名称;2、参数的类型;3、参数的顺序;
但是对JVM而言,方法的签名还包括:4、返回的类型!
演示“完全” Override,即上述4 条件都满足:
class SuperClass{
private final String name;
public SuperClass(String name) {
super();
this.name = name;
}
public String getName() {
return "SuperClass";
}
}
public class OverrideTest extends SuperClass{
private final Date date;
public OverrideTest(String name, Date date) {
super(name);
this.date = date;
}
public Date getDate() {
return date;
}
//覆盖父类的方法,重点是这个
@Override
public String getName() {
return "OverrideTest";
}
}
通过 RefFieldMethodDetails,来查看OverrideTest 类的域和方法:
@Test
public void testGetName() {
RefFieldMethodDetails.details(OverrideTest.class);
RefFieldMethodDetails.details2(OverrideTest.class);
}

这和我们理解的“覆盖”相吻合!即,始终只有一个方法签名的方法。
下面来看看,“不完全”覆盖,即参数类型是继承关系(泛型的特殊处理,一般情况是重载)或返回类型不同时的情况:
class Pair<T> {
private T first;
private T second;
public Pair() {
first = null;
second = null;
}
public Pair(T first, T second) {
this.first = first;
this.second = second;
}
public T getFirst() {
return first;
}
public T getSecond() {
return second;
}
public void setFirst(T newValue) {
first = newValue;
}
public void setSecond(T newValue) {
second = newValue;
}
}
public class DateInterval extends Pair<Date>{
//参数类型——有继承关系
@Override
public void setSecond( Date second ){
if( second.compareTo( getFirst()) >= 0 ){
super.setSecond( second );
}
}
//返回类型不同
@Override
public Date getSecond(){
return (Date)super.getSecond();
}
}
通过 RefFieldMethodDetails,来查看 DateInterval 类的域和方法:
@Test
public void testOverride() {
//打印DateInterval 的所有域和方法(包括private 不包括父类的)
RefFieldMethodDetails.details( DateInterval.class );
//打印DateInterval 的所有公共域和方法(包括父类的)
RefFieldMethodDetails.details2( DateInterval.class );
}

“桥方法”的任务就是调用子类相应的“不完全”覆盖的方法。
常用的“桥方法”实现有,clone 方法