使用泛型删除未经检查的强制转换警告
我刚刚使用
Java进入泛型,所以我为自己设置了一个小项目.我想制作一个Vector / Point,你可以指定数字(例如Double,Integer,Long等).
我最终得到了一个体面的类对象,但是注意到有关这些方法的一些问题. import java.math.BigDecimal; @SuppressWarnings("WeakerAccess") // Suppresses weaker access warnings public class Vector<T extends Number> { private T x; private T y; public Vector() {} public Vector(T x,T y) { this.x = x; this.y = y; } public T getX() { return x; } public void setX(T x) { this.x = x; } public T getY() { return y; } public void setY(T y) { this.y = y; } public void dislocate(T offsetX,T offsetY) { this.setX(addNumbers(getX(),offsetX)); this.setY(addNumbers(getY(),offsetY)); } public void dislocate(Vector vector) { this.setX(addNumbers(getX(),vector.getX())); this.setY(addNumbers(getY(),vector.getY())); } @SuppressWarnings("unchecked") // Suppresses cast unchecked warnings private T addNumbers(Number... numbers) { BigDecimal bd = new BigDecimal(0); for(Number number : numbers) { bd = bd.add(new BigDecimal(number.toString())); } return (T) bd; } } 最后一个方法,即添加数字方法,抛出未经检查的强制转换警告.在我做了一些研究之后,我发现它由于泛型而表现得很奇怪,我是相对较新的并且无法正确排除故障. 返回(T)bd怎么样;创建警告? T必须是Number的实例,所以它应该可以转换为BigDecimal,对吧? 所以我创建了我的小测试方法, Vector<Double> vec = new Vector<>(1.0,3.0); Vector<Double> vec2 = new Vector<>(2.2,3.9); vec.dislocate(1.0,2.7); System.out.println(vec.getX() + " " + vec.getY()); vec.dislocate(vec2); System.out.println(vec.getX() + " " + vec.getY()); 效果很好,打印出2.0 5.7和4.2 9.6. 那么问题是,当我使用Double的方法时,比如Double#isNaN().然后抛出ClassCastException,在线程“main”java.lang.ClassCastException中抛出异常:java.base / java.math.BigDecimal不能转换为java.base / java.lang.Double. 这似乎与人们对此有的其他问题相当普遍,但是,尽管超出了资源,我不明白为什么使用Double方法抛出错误.演员之后对象应该是Double,对吧? 解决方法
要解决这个问题,您需要提供一些添加Ts的方法.
例如,BinaryOperator< T>是两个Ts,并返回一个T.所以,你可以定义添加,例如: BinaryOperator<Double> addDoubles = (a,b) -> a+b; BinaryOperator<BigDecimal> addBigDecimals = (a,b) -> a.add(b); 现在,您实际上需要在创建Vector时向其提供此实例,例如作为构造函数参数: public Vector(BinaryOperator<T> adder) { this.adder = adder; // define a field,too. } 现在使用BiFunction添加数字: private T addNumbers(T a,T b) { return adder.apply(a,b); // or you could just invoke this directly. } 我简化了你的addNumbers总是带两个参数,因为你只用两个参数调用.要做到这一点,你需要提供一个“通用零”,即类型T的值,对于该类型为零,或者只是从varargs数组中的第一个元素开始. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |