我在执行Casting时遇到运行时异常,如下所示
线程“main”中的异常java.lang.ClassCastException:A不能转换为B 在Testing.main(Testing.java:5)
public class A {
public void printA()
{
System.out.println("A");
}
}
public class B extends A{
public void printB()
{
System.out.println("B");
}
}
public class Testing {
public static void main(String args[]) {
B b = (B) new A();
b.printA();
}
}
但为什么这段代码运行良好
因为我们在这里做同样的事情
HttpServletRequest request = (HttpServletRequest) req;
public class LogFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res,FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
String ipAddress = request.getRemoteAddr();
chain.doFilter(req, res);
}
答案 0 :(得分:7)
由于req
的实际类型为HttpServletRequest
,因此可以进行下调。
您可以使用System.out.println(req.getClass());
但是在您的情况下,由于A
,您的实际对象属于new A()
类型,因此 无法将 投射到B
}
正在运行的方案:
A a = new B(); //actual type is B
B b = (B)a;
第二个语句B b = (B)a;
是允许的,因为创建对象的实际类型是B
,因为new B()
,只有引用类型为A
。这就是为什么你可以再次将其强制转换回B
。
答案 1 :(得分:5)
你没有做同样的事情。
在你的第二个例子中,req是HttpServletRequest的一个实例。
在你的第一个例子中,A不是B的实例。
答案 2 :(得分:2)
考虑一下,A是Animal,B是Buffalo。
然后,在您的代码中,您执行:
这是错误的,因为动物没有扩展布法罗!
因此,如果您有一个扩展Animal的Buffalo,您可以将它投射到Animal(因为它是一个)。
答案 3 :(得分:1)
你告诉编译器(通过显式强制转换)相信你没有犯错,所以它忽略了错误并且在编译时没有检测到它。这就是为什么你没有得到编译错误。但是当程序运行时,您将获得异常,因为A
不是 B
的实例。你可能想这样做:
A b = (A) new B();
请注意,如果删除显式强制转换,则会出现编译错误(这总是更可取),因为编译器已经知道您犯了错误。
在另一个例子中,你认为它是相同的......嗯......它不一样,req
是HttpServletRequest
的一个实例。
答案 4 :(得分:1)
当您执行new A
时,您无法将其强制转换为B
,因为B
是A
的子类(否则属性和方法中定义的属性) B
但不是A
看起来像?)
在HttpServletRequest request = (HttpServletRequest) req;
,req
是在其他地方创建的,它是HttpServletRequest
答案 5 :(得分:0)
原因HttpServletRequest
是ServletRequest
。
在您的示例A
中,B
不是A
,可以是C
或class Animal{}
class Dog extend Animal{}
class Cat extend Animal{}
或其他任何子类。
让我们看看更容易动物的例子。
Animal a= new Animal();
Dog dog = (Dog)a;// A dog is an animal but not all animals are dog
主要。
ClassCastException
动物不能是一只狗可以是猫或其他类似于动物的东西,然后抛出instanceof
。要避免此runtimeException,可以使用{{1}}运算符。
答案 6 :(得分:0)
这不会引发异常,因为servletrequest是HttpServletRequest的超级接口。
这与动态多态性的行类似。 如果您编写了一个接口B,然后将A对象转换为B,那么它将起作用。
http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletRequest.html