[英]Runtime exception when doing a Casting
进行Casting时出现运行时异常,如下所示
线程“主”中的异常java.lang.ClassCastException:无法在Testing.main(Testing.java:5)上将A强制转换为B
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);
}
由于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
您不是在做同一件事。
在第二个示例中,req是HttpServletRequest的实例。
在第一个示例中,A不是B的实例。
考虑一下,A是动物,B是布法罗。
然后,在您的代码中执行以下操作:
这是错误的,因为动物没有扩大水牛城!
因此,如果您有扩展“动物”的水牛城,则可以将其投射为“动物”(因为它是其中一个)。
您是在告诉编译器(通过显式强制转换)信任您您没有犯错误,因此它忽略了错误并且在编译时未检测到错误。 这就是为什么您不会遇到编译错误的原因 。 但是,当程序运行时,您会得到一个异常,因为A
不是 B
的实例。 您可能想做:
A b = (A) new B();
请注意,如果删除显式强制转换,则会出现编译错误 (总是首选),因为编译器已经知道您在做错误。
在另一个示例中,您认为它是相同的..嗯..这是不相同的,那里, req
是HttpServletRequest
一个实例。
当你做一个new A
,你不能将它转换为B
,因为B
是的子类A
(又该否则属性和mothods定义B
,但不是A
样子?)
在HttpServletRequest request = (HttpServletRequest) req;
, req
是在其他地方创建的,它是一个HttpServletRequest
原因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
动物不可能是狗,也可能是猫,或者像本例中的Animal这样的其他东西,然后ClassCastException
。 为了避免此runtimeException,可以使用instanceof
运算符。
这不会引发异常,因为servletrequest是HttpServletRequest的超级接口。
这类似于动态多态性。 如果您编写了一个接口B,然后将A对象转换为B,那么它将起作用。
http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletRequest.html
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.