我们可以通过两种方式实现输出:一种是类型转换,一种是没有类型转换
A a=new B() // without typecaste
A a = (A)a// with Typecaste
在两种方式中我们得到相同的输出。那么,类型转换的用途是什么
答案 0 :(得分:1)
我们假设您有一个Animal
的列表。你有Tiger
和Lion
个。
ArrayList<Animal> animals = new ArrayList<>();
//add some Tigers and some Lions
//sort so Tigers are at the beggining of the list
Tiger t = (Tiger)animals.get(0);
如果没有强制转换,您将在编译时获得类型不匹配。通过演员阵营,您只有ClassCastException
的风险try-catch
它只是在Java中正确使用类转换的一个例子。
答案 1 :(得分:0)
Casting用于“相反的方向”,即转换为原始表达式的子类型的表达式。
实施例
鉴于
Object o = "Hello World";
String s = o;
无法编译,但
String s = (String) o;
编译。这可能会产生ClassCastException
,例如如果Integer
中存储o
。
答案 2 :(得分:0)
A a = new B();
仅在B
继承A
时才有效。
如果B
继承自A
,则不需要进行类型转换,因为B 是 A.如果需要将类型转换为子类,则需要进行类型转换:
A a = new B();
B b = (B) a;
虽然这是非法的:
A a = new A();
B b = (B) a;
a
不是B
。
答案 3 :(得分:0)
Java隐式地使用赋值进行向上转换,因此在您提供的代码中,转换运算符是多余的; a
已经是A
类型:
A a = new B(); // without typecast operator (implicit upcast)
A a = (A)a; // with redundant typecast operator
拥有一个强制转换运算符的一个原因是你可能也希望向下转换(这不是在Java中隐式完成的)。例如,当a
是对类A
的对象的类型B
引用时(例如,当B
是A
的子类时),可能需要向下转换以访问某些方法:
A a = new B(); // implicit upcast
C c = ((B)a).methodOfBOnly(); // explicit downcast
您可能还想检查this question有关Java不进行隐式向下转换的原因。
有时也需要明确地进行向上转换。例如,如果一个类包含重载方法
C method(A x){/*does one thing*/}
C method(B x){/*does another*/}
并假设b
的类型为B
,对method((A)b)
和method(b)
的调用行为会有所不同。
答案 4 :(得分:0)
Casting有不同的用途。遗憾的是,您的示例并未执行任何有用的强制转换示例,因为您创建了A
(a
)的实例,然后将其转换为A
。
您需要了解的是明显类型和实际类型。表观类型为List<T> list;
。在这里,我们看到它是一个列表。但实际类型可能是ArrayList<T>
(List<T> list = new ArrayList<>();
)。在这种情况下,我们可以小心地将表观类型转换为实际类型。这将允许我们使用实际类型的功能。例如,让我们看一些代码;给出:
List<Integer> list = new ArrayList<>();
ArrayList<Integer> aList;
LinkedList<Integer> lList = new LinkedList<>();
我们可以毫无问题地做到这一点(虽然一般都很危险)......
// Dangerous but OK with a cast
// list might not be an ArrayList
aList = (ArrayList<Integer>) list;
// Use ArrayList methods
aList.trimToSize();
list = lList;
LinkedList<Integer> danger = (LinkedList<Integer>) list;
......但也可以这样做:
aList = (ArrayList<Integer) list;
// Use ArrayList methods
aList.trimToSize();
// list = lList;
LinkedList<Integer> danger = (LinkedList<Integer>) list;
最后一个代码段产生ClassCastException
,因为list
不是LinkedList
。
但是,施法超越了这一点。考虑什么时候你想要分割两个整数。如果没有强制转换,您可能会得到一个整数结果,其中浮点更合适。考虑:
int i = 2;
int j = 3;
System.out.println("No cast: " + i/j + " ;With cast: " + (double)i/j);
输出:
无演员:0;演员:0.6666666666666666
所以,这取决于用例。
答案 5 :(得分:-2)
A a=new B()
仅在class B
扩展class A
时适用。通过这种方式,class B
以外的class A
中可用的额外方法将随reference a
一起提供。
当你这样做时
A a = (A)a
然后实际上你将class B
的对象强制转换为class A
的对象。确实,孩子可以被父母打字。在此声明之后,reference a
将无法调用class B
中不在class A
内的任何方法,因为现在reference a
指向class A
的对象
在许多情况下都很有用。 例如,您希望拥有指向相同基类的对象集合。您可以维护单个基类集合,而不是为每个子类维护单独的集合。然后,当您想要使用任何子对象时,键入将基类对象强制转换为子类对象来执行此操作。
ArrayList<Base> children = new ArrayList<Base>();
children.add(new Child1());
children.add(new Child2());
Console.WriteLine(((Child1)children.get(0)).getChildName());
Console.WriteLine(((Child2)children.get(1)).getChildName());
现在基类没有任何名为getChild1Name
或getChild2Name
的方法。并且你需要将基类的对象类型化到相应的子类来做那个。