在Java中变量赋值期间是否有用于转换的内容?
例如,我有两个类,Person和Student,它们继承自人:
然后在主要内容中我有以下代码:
Student S = new Student(1, 4.00);
Person P = (Student)S;
System.out.println(P.getId() + " " + ((Student)P).getGpa());
IntelliJ告诉我P = (Student)S
中的强制转换是多余的,如果我在调用getGpa方法时强制转换它就可以了:
Student S = new Student(1, 4.00);
Person P = S;
System.out.println(P.getId() + " " + ((Student)P).getGpa());
但是,如果我在分配期间进行投射,但在调用getGpa时不会再次出现错误:
Student S = new Student(1, 4.00);
Person P = (Student)S;
System.out.println(P.getId() + " " + P.getGpa());
所以我的问题是 - 在分配期间进行投射是否有用?或者它是否被允许但总是多余的,因为您仍然需要告诉编译器您正在转换为子类型的每个方法调用?
感谢您的帮助。
答案 0 :(得分:2)
IntelliJ告诉我
P = (Student)S
中的投射是多余的
这是绝对正确的。 Person
是Student
的基类,因此任何Student
都自动为Person
。
所以我的问题是 - 在分配期间进行投射是否有用?
不,它是多余的,它会降低代码的可读性。
即使必须以统一的方式处理派生对象,例如将它们存储在基类型的对象集合中,例如,对基类的强制转换仍然无用,例如。
List<Person> list = new ArrayList<>();
...
Student student = new Student();
...
list.add((Person)student); // <<= This is redundant, too. Don't do it.
答案 1 :(得分:2)
当你知道编译器没有的东西时,在赋值期间进行转换并不是多余的。
当您将Student
对象分配给Person
变量时,无需强制转换,因为编译器知道Student
继承自Person
。但是如果将Person
对象分配给Student
变量,则编译器不知道Person
对象是否也是Student
对象。
在这种情况下,您必须在分配期间使用强制转换来告诉编译器您知道此特定Person
对象也是Student
。您通常会先使用instanceof
验证这一点。
if (P instanceof Student) {
Student S2 = (Student) P; // here the casting during assignment is required
S2.getGpa();
}
答案 2 :(得分:0)
当您确定A类的对象实际上是子类B的对象并且您无法以任何其他方式在程序中表达该知识时,强制转换非常有用且通常是必需的。
答案 3 :(得分:0)
在P = (Student)S
的情况下,如果S是Student
的实例,那么执行此操作没有任何好处,因为编译器已经知道这一点。
如果你后来有Student Q = P
但是这不起作用,你需要写Student Q = (Student)P
。需要演员表的原因是不能保证P实际上是学生(例如,它可能是导师,也是一个人)。