Java泛型类同类型参数对象调用方法报错的原因及修正咨询
一、初始代码的错误原因
你的第一个AbsCompare方法定义为:
boolean AbsCompare(T Obj){ if( Math.abs( ObjNum.doubleValue())== Math.abs( obj.doubleValue()) return true; else return false; }
方法的参数类型是泛型T(当你实例化MyGen<Integer>时,T就确定为Integer),因此它仅接受T类型的参数,也就是Integer对象。
你调用时传入的Objint2、Objint1是MyGen<Integer>类型的对象,并非Integer类型,类型完全不匹配,所以编译报错;而Objint3是标准的Integer对象,完全符合参数类型要求,因此编译通过。
另外注意代码里的语法小问题:方法参数名是Obj,但你写的是obj.doubleValue(),大小写不匹配,这也是编译错误点之一。
二、修改后方法的错误与解决原理
当你把方法改为:
boolean AbsCompare(MyGen<T> obj)
1. 传入普通Integer对象报错的原因
此时方法参数要求的是MyGen<T>类型(也就是MyGen<Integer>),而Objint3是Integer类型,和MyGen<Integer>属于完全不同的类型,类型不兼容,因此编译报错。
2. 方法内Obj.doubleValue()报错的原因
obj是MyGen<T>类型的对象,这个类本身没有doubleValue()方法——doubleValue()是Number类(T的父类)的方法,只有MyGen类里的ObjNum成员(T类型)才继承了这个方法。你需要通过obj.ObjNum访问该成员后,再调用doubleValue()。
3. 修改后同泛型类对象调用正常的原理
修改后的方法参数类型是MyGen<T>,当你实例化MyGen<Integer>后,T被确定为Integer,参数要求也就明确为MyGen<Integer>类型的对象,Objint1、Objint2正好符合这个类型,所以类型匹配,编译通过。
修正后的完整代码示例
如果想要同时支持比较MyGen<T>对象和T类型对象,可以重载方法:
class MyGen<T extends Number> { T ObjNum; MyGen(T obj) { ObjNum = obj; } // 比较T类型对象 boolean AbsCompare(T obj) { return Math.abs(ObjNum.doubleValue()) == Math.abs(obj.doubleValue()); } // 比较MyGen<T>类型对象 boolean AbsCompare(MyGen<T> obj) { return Math.abs(ObjNum.doubleValue()) == Math.abs(obj.ObjNum.doubleValue()); } } class Sample { public static void main(String args[]) { MyGen<Integer> Objint1 = new MyGen<>(99); MyGen<Integer> Objint2 = new MyGen<>(100); Integer Objint3 = 101; boolean b1 = Objint1.AbsCompare(Objint2); // 正常编译 boolean b2 = Objint1.AbsCompare(Objint1); // 正常编译 boolean b3 = Objint1.AbsCompare(Objint3); // 正常编译 } }
内容的提问来源于stack exchange,提问作者Sumit Baloda

