以我们转换基元数据类型的方式转换对象

时间:2017-04-16 04:14:09

标签: java

我有三个班级:AAA和Top。 A和AA延伸顶部。

为什么这不会编译:

A a = new A();
AA aa = (AA)a;

但这会:

float f = 4.3f;
int i = (int) f;

3 个答案:

答案 0 :(得分:1)

A和类AA位于同一层次结构中,但它们是并排的,因此它们不能彼此强制转换。

让我们说类A定义如下:

public class A extends Top{

   public A() {

   }

   public void foo(int i) {
      System.out.println(i);
   }

}

该课程AA的定义如下:

public class AA extends Top {

   public AA() {

   }

   public void bar(String s) {

   }

}

现在让理论上想象一下如果你试图将A强制转换为AA并且它有效的话会发生什么:

A a = new A();
(AA) aa = (AA) a;

由于aa静态类型AA,因此Java会让您编写如下代码:

aa.bar("hi!");

由于AA类有一个条形方法,但是aa动态类型A,这意味着变量的实际对象{ {1}}指的是没有有一个名为aa的方法。

(对象的静态类型告诉您可以在其上调用哪些方法,动态类型告诉您它实际具有哪些方法。)

因此,Java会告诉bar("hi!")执行aa,但bar("hi!")不知道该怎么做,因为aa没有定义aa方法

答案 1 :(得分:0)

您可以在要强制转换的类中创建强制转换方法。这里我使用a.cast(B b)方法将类型转换为类型A.

public class A {
    public int i;
    public  A cast(B b){
        A a = new A();
        a.i=b.i;
        return a ;
     }
}

public class B {
    public int i=10;
}



public class Tester {
    public static void main(String[] args) {
        B b = new B();
        A a= new A();
        a=a.cast(b);
        System.out.println(a.i);
    }
}

答案 2 :(得分:0)

Java是一种强类型编程语言,它意味着定义每个变量,需要指定其类型,而对于每个变量,它只能保存属于同一类型的值。对于原始类型,Java还定义了如何将不同类型相互转换的规则,Widening Primitive Conversion(无信息丢失)和Narrowing Primitive Conversion(信息可能丢失),您可以找到更多详细信息在the official Java docs。因此,你可以int i = (int) f;的原因是转换规则是在Java规范和Java编译器中定义的,允许你这样做。如果您尝试过,则无法int a = (int) true,因为没有将boolean类型转换为int的规则。

引用类型的类型转换规则也很简单,编译器只允许您在认为A a = (A) b 的类型 b时执行类型转换A或者类型层次结构中sub-type的{​​{1}},请看下面的代码:

A

编译器只知道b是类型Object b = c; A a = (A) b; 但不知道它的特定类型,因为Object是Java类型层次结构的Object,所以{{1}的实际类型也许是任何类型,比如类型root,所以编译器允许你这样做。如果b实际上一个A,则只有在投放b时才能在运行时找到错误。

另一方面,当明确知道 A不是ClassCastException类型时,编译器会阻止您执行A a = (A) b

b

如果您具有类型Aclass A {} class B {} 的上述定义,那么编译器有足够的信息表明实例A绝对不是B类型,因此它会给出当您尝试B时,编译错误为A。这是使用强类型编程语言的一大好处:保证类型安全(在Java的编译时)。