我有两个类似的方法。一个用于处理对象,其他 vector :
@SuppressWarnings("unused")
private void printRows(PrintWriter out, Vector<?> dataOb,
String[] columns, String[] columnType,
Hashtable<?, ?> columnAccessors,
String trOptions, String tdOptions)
throws ServletException
{
System.out.println("At Printing Rows, Vector...");
// If the object is a vector, loop through the elements.
Vector<?> v = (Vector<?>) dataOb;
Enumeration<?> e = (Enumeration<?>) v.elements();
while (e.hasMoreElements())
{
tryRow(out, e.nextElement(),
columns, columnType, columnAccessors, trOptions, tdOptions);
}
}
private void printRows(PrintWriter out, Object dataOb,
String[] columns, String[] columnType,
Hashtable<?, ?> columnAccessors,
String trOptions, String tdOptions)
throws ServletException
{
System.out.println("At Printing Rows, Object...");
// If the object is an array, loop through the objects.
Object[] objects = null;
try {objects = (Object[]) dataOb;}
catch (Exception e1) { ExceptionToolkit.exceptionHandler (e1, "Can't assign data to objects"); }
System.out.println("At Printing Rows, have objects...");
for (Object object: objects)
{
System.out.println("At Printing Rows, have objects, looping...");
tryRow(out, object, columns, columnType, columnAccessors, trOptions, tdOptions);
}
}
如果我正确理解 Java 和多态性,如果使用 vector 调用方法,则应调用第一个函数,但如果我使用其他任何对象调用它,则应调用第二个方法。
但是,当我的程序去调用该函数时,不知何故它得到了错误的函数,因为我没有正确处理,而是得到了这个:
CLASS: class hu.flux.models.PersonColumn: name
CLASS: class hu.flux.models.PersonColumn: phone
At Printing Rows, Object...
Can't assign data to objects: java.lang.ClassCastException: java.util.Vector cannot be cast to [Ljava.lang.Object;
java.lang.ClassCastException: java.util.Vector cannot be cast to [Ljava.lang.Object;
at hu.flux.tables.TableServlet.printRows(TableServlet.java:97)
at hu.flux.tables.TableServlet.service(TableServlet.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:674)
at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:579)
at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:516)
at org.apache.jasper.runtime.JspRuntimeLibrary.include(JspRuntimeLibrary.java:930)
at org.apache.jsp.ShowPeople_jsp._jspService(ShowPeople_jsp.java:68)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:68)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:376)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:320)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:265)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:674)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:462)
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:401)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:329)
at hu.flux.ControllerServlet.gotoPage(ControllerServlet.java:84)
at hu.flux.ControllerServlet.service(ControllerServlet.java:47)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:243)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:201)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:163)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:108)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:556)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:401)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:242)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:267)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:245)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:260)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)
At Printing Rows, have objects...
如果我正确理解堆栈跟踪,它告诉我它失败了,因为 dataOb 是一个 vector ,但如果这是真的,其他方法不应该捕捉到调用吗?
我是不是误解了 Java 的多态性?签名中的内容应该有所不同吗?我真的需要在调用特定函数之前检查对象是否是 vector 的实例,而不是依赖多态性来处理区别吗?有没有一种好方法可以从一种或另一种 printRows() 方法中解决此问题?
最佳答案
您没有提供足够的信息,所以我有点猜测...如果我在这里所说的不适用,请告诉我。这对调用 printRows 的代码很有用...
如果你这样做:
Object x = new Vector();
printRows(..., x);
那么 printRows(..., Object) 方法将被调用,因为调用什么方法的决定是在编译时而不是运行时完成的。编译器根据声明的变量类型决定调用什么方法。在选择要调用的方法时,任何时候都不会查看对象中的值。
您可以在 printRows(..., Object) 方法的顶部修复此代码:
if(x instanceof Vector)
{
printRows(out, (Vector)dataOb);
}
else
{
....
}
这类似于 this question .
关于java - 为什么在对象和 vector 之间进行选择时,Java 的多态性无法捕捉到正确的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4021116/