Почему полиморфизм Java не в состоянии уловить правильный метод при выборе между объектом и вектором? - PullRequest
3 голосов
/ 26 октября 2010

У меня есть два похожих метода.Один предназначен для обработки объектов, другие векторы:

@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 ()?

Ответы [ 3 ]

4 голосов
/ 26 октября 2010

Неужели я что-то неправильно понял о полиморфизме Java?

Да.Перегруженные методы не подвержены полиморфизму времени выполнения, только переопределенные методы.Выбор между вашими методами происходит во время компиляции в соответствии с объявленным типом ссылки, которую вы передаете в метод.

4 голосов
/ 26 октября 2010

Вы не предоставили достаточно информации, поэтому я немного догадываюсь ... если то, что я здесь говорю, не применимо, пожалуйста, дайте мне знать. Это было бы полезно для кода, который вызывает printRows ...

Если вы сделаете это:

Object x = new Vector();

printRows(..., x);

тогда будет вызван метод printRows (..., Object), потому что разрешение вызываемого метода выполняется во время компиляции, а не во время выполнения. Компилятор решает, какой метод вызывать, основываясь на типе объявленной переменной. Ни при каких обстоятельствах при выборе того, какой метод вызывать, что-либо смотрит на значение в объекте.

Вы можете исправить это, поместив код в верхнюю часть метода printRows (..., Object):

if(x instanceof Vector)
{
    printRows(out, (Vector)dataOb);
}
else
{
   ....
}

Это похоже на этот вопрос .

0 голосов
/ 26 октября 2010

Вы уверены, что вызываете метод с помощью вектора? Вы можете показать нам звонок?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...