MIDletStateMap.getState(...); - AbstractMethodError?
От: Grief Россия Grief-postal.narod.ru
Дата: 15.06.07 11:45
Оценка:
Я вот пишу ява-машину, точнее только начинаю писать, однако вот наткнулся на непонятнео место. в процессе выполнения мидлета мы вызываем статический метод com.sun.midp.midlet.MIDletState.getState(javax.microedition.midlet.MIDlet); — вроде до этого момента все корректно, да и сама возможность вызова метода вполне очевидна — он public. Вот тут моя ява-машина вываливает AbstractMethodError и завершает работу. посмотрел на содержимое этого класса:
public static com.sun.midp.midlet.MIDletState getState(javax.microedition.midlet.MIDlet);
  Code:
   Stack=2, Locals=1, Args_size=1
   0:    getstatic    #2; //Field mapImpl:Lcom/sun/midp/midlet/MIDletStateMap;
   3:    aload_0
   4:    invokevirtual    #3; //Method getStateImpl:(Ljavax/microedition/midlet/MIDlet;)Lcom/sun/midp/midlet/MIDletState;
   7:    areturn
  LineNumberTable: 
   line 45: 0
  LocalVariableTable: 
   Start  Length  Slot  Name   Signature
   0      8      0    m       Ljavax/microedition/midlet/MIDlet;

protected abstract com.sun.midp.midlet.MIDletState getStateImpl(javax.microedition.midlet.MIDlet);

}


и тут мы видим — что? то что метод getState() делает invokevirtual абстрактного метода getStateImpl().... Спрашивается — что я не так понимаю? Метод не нативный, обычный абстрактный метод — его ведь нельзя вызывать. сначала подумал — может где ошибка и должен вызываться метод getState() класса производного от com.sun.midp.midlet.MIDletState, где абстрактный метод getStateImpl() переопределен, но тогда почему метод getState() имеет public-доступ?
Re: MIDletStateMap.getState(...); - AbstractMethodError?
От: dshe  
Дата: 15.06.07 12:00
Оценка:
Здравствуйте, Grief, Вы писали:

G>и тут мы видим — что? то что метод getState() делает invokevirtual абстрактного метода getStateImpl().... Спрашивается — что я не так понимаю? Метод не нативный, обычный абстрактный метод — его ведь нельзя вызывать.


Абстрактные методы можно вызывать, другое дело, что отработать должен метод, которым наследник реализовал этот абстрактный.

ЗЫ Просто любопытство. А зачем ты пишешь свою Java машину?
--
Дмитро
Re[2]: MIDletStateMap.getState(...); - AbstractMethodError?
От: Grief Россия Grief-postal.narod.ru
Дата: 15.06.07 14:27
Оценка:
Нет ни одной ява-машины для кпк с поддержкой Bluetooth, 3D, функций Windows mobile 5.0 и вообще много чего.

Но я не совсем понял ответ на мой вопрос — по моему я ясно выразился и сказал что вызывается именно статический метод этого класса. то есть о наследниках речи не идет
Re[3]: MIDletStateMap.getState(...); - AbstractMethodError?
От: dshe  
Дата: 15.06.07 14:39
Оценка:
Здравствуйте, Grief, Вы писали:

G>Нет ни одной ява-машины для кпк с поддержкой Bluetooth, 3D, функций Windows mobile 5.0 и вообще много чего.


G>Но я не совсем понял ответ на мой вопрос — по моему я ясно выразился и сказал что вызывается именно статический метод этого класса. то есть о наследниках речи не идет


Давай разбираться. Насколько я понял у тебя сомнения по поводу правильности байткода. Хорошо, какой тогда байткод должен генерится на приведенный java код
abstract class MIDletStateMap {
    static MIDletStateMap mapImpl;

    public static MIDletState getState(MIDlet midlet) {
        return mapImpl.getStateImpl(midlet);
    }

    protected abstract MIDletState getStateImpl(MIDlet midlet);
}
--
Дмитро
Re[4]: MIDletStateMap.getState(...); - AbstractMethodError?
От: Grief Россия Grief-postal.narod.ru
Дата: 15.06.07 15:33
Оценка:
D>
D>abstract class MIDletStateMap {
D>    static MIDletStateMap mapImpl;

D>    public static MIDletState getState(MIDlet midlet) {
D>        return mapImpl.getStateImpl(midlet);
D>    }

D>    protected abstract MIDletState getStateImpl(MIDlet midlet);
D>}
D>

{
public static com.sun.midp.midlet.MIDletState getState(javax.microedition.midlet.MIDlet);
Code:
Stack=2, Locals=1, Args_size=1
0: getstatic #2; //Field mapImpl:Lcom/sun/midp/midlet/MIDletStateMap;
3: aload_0
4: invokevirtual #3; //Method getStateImplLjavax/microedition/midlet/MIDletLcom/sun/midp/midlet/MIDletState;
7: areturn
LineNumberTable:
line 45: 0
LocalVariableTable:
Start Length Slot Name Signature
0 8 0 m Ljavax/microedition/midlet/MIDlet;

protected abstract com.sun.midp.midlet.MIDletState getStateImpl(javax.microedition.midlet.MIDlet);

}

Я и не против, чтобы такой код генерировался. Начну издалека, надеюсь вы мне это простите. И не буду приводить полный байткод, чтобы место не тратить.
Итак, класс javax.microedition.lcdui.Display имеет метод getDisplay. Смотрим егобайт код
public static javax.microedition.lcdui.Display getDisplay(javax.microedition.midlet.MIDlet);
  Code:
   Stack=3, Locals=5, Args_size=1
   0:    getstatic    #22; //Field LCDUILock:Ljava/lang/Object;
   3:    dup
   4:    astore_3
   5:    monitorenter
   6:    aload_0
   7:    invokestatic    #23; //Method com/sun/midp/midlet/MIDletStateMap.getState:(Ljavax/microedition/midlet/MIDlet;)Lcom/sun/midp/midlet/MIDletState;

Обращаем внимание на инструкцию под номером семь. видим вызов статического метода getState из класса com.sun.midp.midlet.MIDletStateMap
Смотрим байт-код этого метода:
public static com.sun.midp.midlet.MIDletState getState(javax.microedition.midlet.MIDlet);
  Code:
   Stack=2, Locals=1, Args_size=1
   0:    getstatic    #2; //Field mapImpl:Lcom/sun/midp/midlet/MIDletStateMap;
   3:    aload_0
   4:    invokevirtual    #3; //Method getStateImpl:(Ljavax/microedition/midlet/MIDlet;)Lcom/sun/midp/midlet/MIDletState;
   7:    areturn
  LineNumberTable: 
   line 45: 0
  LocalVariableTable: 
   Start  Length  Slot  Name   Signature
   0      8      0    m       Ljavax/microedition/midlet/MIDlet;

обращаем внимание на инструкцию номер четыре и видим вызов абстрактного метода этого же класса.
Естесственно я абсолютно уверен в правильности байт-кода явы машины, поэтому очевидно, что я упускаю какую-то деталь. Объясните пожалуйста, где здесь вообще присутствует намек на переопределенный абстрактный метод? Да кажется даже если метод переопределен — разве байткод не будет вызывать кодом invokevirtual именно переопределенный метод, а не абстрактный?
Re[5]: MIDletStateMap.getState(...); - AbstractMethodError?
От: Grief Россия Grief-postal.narod.ru
Дата: 16.06.07 06:14
Оценка:
Извините, если вопрос кажется глупым, но я проштудировал спецификацию Java Virtual Machine Specification на предмет вызова методов и все равно не могу понять в чем у меня ошибка.
Re[6]: MIDletStateMap.getState(...); - AbstractMethodError?
От: Grief Россия Grief-postal.narod.ru
Дата: 16.06.07 08:34
Оценка: 1 (1)
ну, да, конечно, я дурак. проглядел:

Let C be the class of objectref. The actual method to be invoked is selected by the following lookup procedure:

* If C contains a declaration for an instance method with the same name and descriptor as the resolved method, and the resolved method is accessible from C, then this is the method to be invoked, and the lookup procedure terminates.

* Otherwise, if C has a superclass, this same lookup procedure is performed recursively using the direct superclass of C ; the method to be invoked is the result of the recursive invocation of this lookup procedure.

* Otherwise, an AbstractMethodError is raised.

Re[3]: MIDletStateMap.getState(...); - AbstractMethodError?
От: Donz Россия http://donz-ru.livejournal.com
Дата: 20.06.07 08:39
Оценка:
Здравствуйте, Grief, Вы писали:

G>Нет ни одной ява-машины для кпк с поддержкой Bluetooth, 3D, функций Windows mobile 5.0 и вообще много чего.

А есть сайт проекта? Можно узнать на какой стадии находишься? За основу взял https://phoneme.dev.java.net?
Дело хорошее, но очень трудоёмкое. Как бы не получилась ещё одна KVM со своими эксклюзивными багами.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.