我有两种类似的方法.一个用于处理对象,其他向量:
@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和多态,如果使用向量调用方法,则应调用第一个函数,但如果我用其他任何对象调用它,则应调用第二个方法.
但是,当我的程序去调用该函数时,不知何故它得到了错误的一个,因为而不是正确处理,我得到这个:
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是一个向量,但是如果这是真的,那么其他方法是否应该捕获该调用?
我是否误解了Java的多态性?签名中的某些内容应该有所不同吗?在调用特定函数之前,我是否真的需要检查对象是否是向量的实例,而不是依靠多态来处理区别?有没有一种很好的方法可以从printRows()方法中的一个或另一个中解决这个问题?
解决方法:
你没有提供足够的信息,所以我猜一点……如果我在这里说的不适用请告诉我.调用printRows的代码会很有用……
如果你这样做:
Object x = new Vector();
printRows(..., x);
然后将调用printRows(…,Object)方法,因为要调用的方法的解析是在编译时而不是运行时完成的.编译器根据声明的变量类型决定调用哪个方法.在选择要调用的方法时,任何时候都不会查看对象中的值.
您可以在printRows(…,Object)方法的顶部修复此类推送代码:
if(x instanceof Vector)
{
printRows(out, (Vector)dataOb);
}
else
{
....
}
这类似于this question.