在java中,泛型提供了一种在编译时检查类型安全性的机制,允许我们定义可操作多种类型数据的类、接口和方法。当我们定义一个泛型类时,例如 class mygen
理解 T 和 MyGen
考虑以下泛型类 MyGen 及其 AbsCompare 方法:
class MyGen{ T ObjNum; MyGen( T obj){ ObjNum = obj; } // 尝试比较一个类型为 T 的对象 boolean AbsCompare( T Obj){ return Math.abs( ObjNum.doubleValue()) == Math.abs( Obj.doubleValue()); } }
以及在 main 方法中的使用:
class Sample {
public static void main(String args[]){
MyGen Objint1 = new MyGen<>( 99);
MyGen Objint2 = new MyGen<>( 100 );
// 创建一个 Integer 类型对象
Integer Objint3 = 101;
// 调用 AbsCompare 方法进行比较
boolean b1 = Objint1.AbsCompare( Objint2); // 编译错误!
boolean b2 = Objint1.AbsCompare( Objint1); // 编译错误!
boolean b3 = Objint1.AbsCompare( Objint3) ; // 正常编译
}
} 上述代码中,b1 和 b2 的调用会产生编译错误,而 b3 则正常。这是因为 AbsCompare(T Obj) 方法的参数类型是 T。当 Objint1 是 MyGen
这个问题的核心在于对“has-a”和“is-a”关系的理解:
为了能够同时比较 T 类型的对象和 MyGen
通过定义两个 AbsCompare 方法,我们可以分别处理不同类型的参数:
修改后的 MyGen 类如下:
class MyGen{ T ObjNum; MyGen( T obj){ ObjNum = obj; } /** * 比较当前 MyGen 对象内部的 T 类型值与另一个 T 类型值。 * @param otherObj 要比较的 T 类型对象。 * @return 如果绝对值相等则返回 true,否则返回 false。 */ boolean AbsCompare(T otherObj){ return Math.abs(ObjNum.doubleValue()) == Math.abs(otherObj.doubleValue()); } /** * 比较当前 MyGen 对象内部的 T 类型值与另一个 MyGen 对象内部的 T 类型值。 * @param otherMyGen 要比较的另一个 MyGen 对象。 * @return 如果两个 MyGen 对象内部的 T 类型值的绝对值相等则返回 true,否则返回 false。 */ boolean AbsCompare(MyGen otherMyGen){ // 访问 otherMyGen 对象的内部 ObjNum 成员进 行比较 return Math.abs(ObjNum.doubleValue()) == Math.abs(otherMyGen.ObjNum.doubleValue()); } }
现在,main 方法中的所有调用都将正常编译和运行:
class Sample {
public static void main(String args[]){
MyGen Objint1 = new MyGen<>( 99);
MyGen Objint2 = new MyGen<>( 100 );
MyGen Objint4 = new MyGen<>( 99 ); // 用于测试相等
Integer Objint3 = 101;
Integer Objint5 = 99; // 用于测试相等
System.out.println("比较 MyGen 与 MyGen:");
boolean b1 = Objint1.AbsCompare( Objint2); // 调用 AbsCompare(MyGen otherMyGen)
System.out.println("Objint1.AbsCompare(Objint2): " + b1); // false
boolean b2 = Objint1.AbsCompare( Objint4); // 调用 AbsCompare(MyGen otherMyGen)
System.out.println("Objint1.AbsCompare(Objint4): " + b2); // true
System.out.println("\n比较 MyGen 与 Integer:");
boolean b3 = Objint1.AbsCompare( Objint3) ; // 调用 AbsCompare(T otherObj)
System.out.println("Objint1.AbsCompare(Objint3): " + b3); // false
boolean b5 = Objint1.AbsCompare( Objint5) ; // 调用 AbsCompare(T otherObj)
System.out.println("Objint1.AbsCompare(Objint5): " + b5); // true
}
} 通过方法重载,编译器能够根据传入参数的实际类型,自动选择最匹配的 AbsCompare 方法进行调用。
通过上述分析和示例,我们可以看到,理解Java泛型中类型参数和泛型类实例之间的关系,并恰当运用方法重载,是编写健壮、灵活且类型安全的泛型代码的关键。