将Integer对象转换为双掷错误

时间:2019-04-20 13:25:56

标签: java

我正在尝试编写一个实现Comparable接口的'Cup'类。

我的代码:

func findFriends(text: String) -> Void {

    let ref = Database.database().reference()
    ref.child("users").queryOrdered(byChild: "username").queryStarting(atValue: text).queryEnding(atValue: text+"\u{f8ff}").observe(.value, with: { snapshot in

        let user = User()
        let userArray = [User]()

            for u in snapshot.children{
                user.name = u.value!["name"] as? String
        }
    })

但是程序抛出错误说明: class Cup<T> implements Comparable<T>{ public T radius; public T height; public Cup(T radius, T height){ this.radius = radius; this.height = height; } public double getVolume(){ return (double) radius * (double) radius* (double) height* 3.14 ; // throwing error } public int compareTo(Object cup){ if(getVolume()== ((Cup) cup).getVolume()){ // cannot access java.lang.Comparable return 0; } else if(getVolume() > ((Cup) cup).getVolume()){ return 1; } else if(getVolume() < ((Cup) cup).getVolume()){ return -1; } return -2; } } class test{ public static void main(String[] args) { Cup<Integer> mycup = new Cup<Integer>(5,5); Cup<Integer> momscup = new Cup<Integer>(7,7); mycup.compareTo(momscup); } }

我不是要转换为Double,而是要转换为Double。为什么会引发错误?

谢谢

3 个答案:

答案 0 :(得分:5)

  

我不是要转换为Double,而是要转换为Double。为什么会引发错误?

问题的根源是T的静态类型是Object而不是Integer。因此,编译器已确定以下路径可能有效:

  1. 将对象的实际类型设置为Double(需要运行时检查)
  2. Double开箱到double

问题是Integer无法转换为Double

最好的解决方案是这样:

class Cup<T extends Number> implements Comparable<T> {
    ...
    public double getVolume(){
        return radius.doubleValue() * radius.doubleValue() 
               height.doubleValue() * Math.PI;
    }

这是静态类型安全的(对您可能在其他地方执行的任何不安全的转换进行模运算)。


请注意,如果将T替换为Integer,则编译器将使用其他路径进行转换:

  1. Integer开箱到int
  2. int扩展为double

取决于确切地编写πr 2 h表达式的方式,类型转换可能是不必要的。

答案 1 :(得分:2)

实际上,您实际上是在botium-ScriptingProvider undefined PARTIAL_HELLO ({ convoDir: 'sample/', filename: 'example.pconvo.txt' }): Line 3: #me - Hello, Bot! | Line 6: #bot - You said: Hello, Bot! +0ms 上隐式添加一个强制类型转换,因此您将获得异常。

我建议您对课程进行如下更改:

Double

仔细查看我如何更改class Cup<T extends Number> implements Comparable<Cup<T>> { public T radius; public T height; public Cup(T radius, T height) { this.radius = radius; this.height = height; } public double getVolume() { return radius.doubleValue() * radius.doubleValue() * height.doubleValue() * 3.14; } @Override public int compareTo(Cup<T> cup) { return Double.compare(getVolume(), cup.getVolume()); } } 方法和compareTo方法以使其更具可读性。

在完成这些更改之后,您将无法运行测试:

getVolume

以下是我建议您进行的更改,以便您可以学习。

  • 从有效Java条款31开始,您应该使用有界通配符来增加API的灵活性。 (阅读有效Java的泛型一章,将非常有帮助)
  • 使用class test { public static void main(String[] args) { Cup<Integer> mycup = new Cup<>(5, 5); Cup<Integer> momscup = new Cup<>(7, 7); mycup.compareTo(momscup); } } ,这是一种方便的方法,已经可以用来完成您想要的操作。
  • 如果要覆盖方法,请使用Double.compare
  • @Override初始化时,您无需再次在右侧提及Cup<Integer> mycup = new Cup<>(5, 5);。 (如果您使用的是JDK 7或更高版本,则可以这样做)

答案 2 :(得分:0)

半径和高度属性定义为T,但是将它们强制转换为double,则应将它们声明为double或使类的Generic类型扩展Number,Number是Double和Integer的抽象父类

class Cup<T extends Number> {

    public T radius;
    public T height;

    public Cup(T radius, T height) {
        this.radius = radius;
        this.height = height;
    }

    public double getVolume() {

        return radius.doubleValue() * radius.doubleValue() * height.doubleValue() * 3.14; // throwing error 
    }

}

class test {

    public static void main(String[] args) {

        Cup<Integer> mycup = new Cup<Integer>(5, 5);

        Cup<Integer> momscup = new Cup<Integer>(7, 7);

        System.out.println(mycup.getVolume());
    }
}