Форум: "Прочее";
Текущий архив: 2007.03.25;
Скачать: [xml.tar.bz2];
ВнизВот так фокус !!! Найти похожие ветки
← →
Юрий Зотов © (2007-02-28 18:23) [0]Java, Eclipse. Один из классов имеет такой метод:
public void selectionChanged(IAction action, ISelection selection) {
action.setEnabled(!ReplicationFactory.isCenter);
... // На этой строке стоит BreakPoint
}
isCenter - статическое булевское поле класса ReplicationFactory. Запускаю и прихожу на BreakPoint (то есть, предыдущая строка только что выполнилась). Стоя на этом брейке, проверяю значения выражений:ReplicationFactory.isCenter
- показывает false.action.isEnabled()
- показывает false. Несмотря на not!
Что за чудеса? Ладно, ввожу локальную переменную:
public void selectionChanged(IAction action, ISelection selection) {
boolean isCenter = ReplicationFactory.isCenter;
action.setEnabled(!isCenter);
... // На этой строке стоит BreakPoint
}
И все работает. То ли лыжи не едут, то ли еще что, но фокус мне понравился. Из-за этого бага полчаса времени потерял, блин.
← →
Ketmar © (2007-02-28 18:26) [1]java...
← →
ferr © (2007-02-28 18:31) [2]Скорее Eclipse что-то неправильно делает..
← →
Юрий Зотов © (2007-02-28 18:35) [3]> ferr © (28.02.07 18:31) [2]
Вряд ли. Я ведь потому туда и полез, что сама программа работала неверно.
← →
wicked © (2007-02-28 18:37) [4]хм... а версия компилятора/JDK какая?
и еще крамольный мысль есть - а мож javac считает, что приоритет оператора "!" больше, чем оператора "."?
тогда, если так попробовать?public void selectionChanged(IAction action, ISelection selection) {
action.setEnabled(!(ReplicationFactory.isCenter));
... // На этой строке стоит BreakPoint
}
← →
ferr © (2007-02-28 18:38) [5]> и еще крамольный мысль есть - а мож javac считает, что приоритет
> оператора "!" больше, чем оператора "."?
маразм.
← →
ferr © (2007-02-28 18:43) [6]А по существу сказать нечего.. Ошибка может быть даже в 17-ой строке ;-). А Вы не могли бы "обрезать" до компилируемого примера?
← →
Рамиль © (2007-02-28 18:45) [7]
> wicked © (28.02.07 18:37) [4]
Это как? А что тогда должно получится в результате !ReplicationFactory?
← →
Ученик чародея © (2007-02-28 18:46) [8]Нда, если Зотов взялся за Java, то Delphi конец.
← →
wicked © (2007-02-28 18:51) [9]> Рамиль © (28.02.07 18:45) [7]
"!" - оператор булевского отрицания, его результатом есть bool
соответственно, его аргумент также приводится к булевскому выражению - так принято почти во всех си-образных языках...
поэтому, если ReplicationFactory содержит валидную (а других, примем, в java нету) ссылку на обьект, то !ReplicationFactory вернет false
и наоборот - если ReplicationFactory не содержит ссылок, сиречь есть NULL, то !ReplicationFactory вернет true
по моему так (цы) - на истину не претендую
← →
Юрий Зотов © (2007-02-28 18:52) [10]> Ученик чародея © (28.02.07 18:46) [8]
Почему? Я и Delphi не забываю. Просто участвую не в одном проекте, а они на разных языках, так что пришлось освоить. Благо, что несложно, да и для кругозора полезно.
← →
Ketmar © (2007-02-28 18:55) [11]хм. щаз опять вместо полезть и глянуть приоритеты -- разведём флуд на 20 страниц. %-)
← →
Юрий Зотов © (2007-02-28 19:16) [12]> wicked © (28.02.07 18:51) [9]
Попробовал вычислить выражение !ReplicationFactory - говорит, что ReplicationFactory невозможно разрешить. Убрал not - то же самое. То есть, класс ReplicationFactory, среде, видите ли, в данном месте кода неизвестен - хотя вполне успешно компилируется и работает.
В общем-то, оно и понятно, почему - среде надо писать "class": ReplicationFactory.class - вычисляется прекрасно. Все ОК.
!ReplicationFactory.class - "оператор ! для этого типа не определен". Тоже ОК.
В другом месте был совершенно аналогичный кусок, но без not:action.setEnabled(ReplicationFactory.isCenter);
и тоже не работал. Ввел локальную переменную - заработало.
Подозреваю, что эта непонятная байда связана с тем, что поле ReplicationFactory.isCenter - статическое. Но почему и как связана - не понимаю. ИМХО, это все же глюк, такого быть не должно.
← →
Суслик © (2007-02-28 19:19) [13]
> ИМХО, это все же глюк, такого быть не должно.
у меня все работает.
как у тебя объявлено isCenter?
← →
Суслик © (2007-02-28 19:23) [14]вообще странно - и так и сяк у меня работает.
может все-таки 17ая строка? А?
← →
Юрий Зотов © (2007-02-28 19:27) [15]> Суслик © (28.02.07 19:19) [13]
Это просто константа, используемая для переключения контекста всей программы разом:
public class ReplicationFactory {
public static final boolean isCenter = false;
...
}
← →
Суслик © (2007-02-28 19:28) [16]аналогично.
тогда и правда баг, наверное
а java какая?
← →
Юрий Зотов © (2007-02-28 19:30) [17]> Суслик © (28.02.07 19:23) [14]
> может все-таки 17ая строка?
Да хоть 117-я. Ты можешь объяснить, почему один и тот же код БЕЗ абсолютно лишней промежуточной локальной переменной - НЕ работает, а с ней - работает?
На что и как она влияет, эта переменная?
← →
Юрий Зотов © (2007-02-28 19:32) [18]> Суслик © (28.02.07 19:28) [16]
java version "1.5.0_10"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_10-b03)
Java HotSpot(TM) Client VM (build 1.5.0_10-b03, mixed mode, sharing)
← →
Суслик © (2007-02-28 19:35) [19]у меня 1.5.0_06
так что сказать сложно.
А вот сейчас 11 забабахию - в смысле обновлю:)
← →
Канадец (2007-02-28 19:42) [20]>Юрий Зотов ©
public static final boolean isCenter = false;
когда-нибудь менялась? Ну например было такpublic static final boolean isCenter = true;
, а потом поменяли.
← →
Юрий Зотов © (2007-02-28 19:44) [21]> Суслик © (28.02.07 19:35) [19]
А я боюсь обновлять. Проект на этапе сдачи, последние бантики прикручиваю, а сроки, как обычно, горят. Обновишь - не дай Бог, что-нибудь рухнет, тогда ваще полный капут настанет.
Вот сдам - обновлюсь.
← →
Суслик © (2007-02-28 19:47) [22]Блин, Юра, а прав, похоже, иноземец то - если билд не делать, то смена значения true на false не сказывается - только что проверил.
← →
Сотрудник деканата (2007-02-28 19:50) [23]Надо авторебилд включать. И обновить Эклипс до последней версии. В 3.2 по-моему были проблемы с этим..
← →
Суслик © (2007-02-28 19:51) [24]я нетбинсом 4.1 пользуюсь, тут такая же штука.
← →
Суслик © (2007-02-28 19:51) [25]я нетбинсом 4.1 пользуюсь, тут такая же штука.
← →
Канадец (2007-02-28 19:52) [26]
> Суслик © (28.02.07 19:47) [22]
Компилятор просто подставляет константное значение вместо ссылки на класс. Если в классе константа изменилась, компилятору это побоку. Надо либо всё перекомпилировать, либо использовать статический конструктор:public static final boolean isCenter;
static
{
isCenter = false;
}
Хотя всё это к данной проблеме может отношения и не иметь.
← →
Сотрудник деканата (2007-02-28 19:56) [27]> Суслик © (28.02.07 19:35) [19]
А почему не 1.6...?
← →
Юрий Зотов © (2007-02-28 19:57) [28]> Канадец (28.02.07 19:42) [20]
Да, конечно. Эта константа для того и вводилась, чтобы разом переключать режим программы (но не во время ее работы, конечно - потому там и final). То есть, она используется, как некое подобие директивы условной компиляции (если можно так выразиться) и меняется только перед самой компиляцией.
При отладке эту константу не раз туда-сюда переключали (причем, ради перестраховки каждый раз чистились оба workspace - и IDEшный и RCPшный).
Но ведь значение константы отладчик показывает абсолютно правильно. Почему же, пока тупо не введешь ее промежуточное запоминание, имеем глюк?
← →
iZEN © (2007-02-28 20:00) [29]
> Юрий Зотов © (28.02.07 18:23)
> И все работает. То ли лыжи не едут, то ли еще что, но фокус
> мне понравился. Из-за этого бага полчаса времени потерял,
> блин.
Я же предупреждал, что пошаговая отладка в многопоточном приложении НЕ_РАБОТАЕТ.
Используйте JUnit.
← →
Канадец (2007-02-28 20:02) [30]
> Юрий Зотов © (28.02.07 19:57) [28]
С отладчиком понятно почему. Отладчик "берёт" её прямо из класса, а там значение уже новое. Что касается промежуточной переменной... по логике вещей туда тоже должна подставлятся константа и смысл меняться не должен, а на самом деле кто его знает... Попробуйте со статическим конструктором. Если работает то проблема именно в этом.
← →
Суслик © (2007-02-28 20:03) [31]
> [27] Сотрудник деканата (28.02.07 19:56)
> > Суслик © (28.02.07 19:35) [19]
>
> А почему не 1.6...?
да я так - чисто для себя, иногда пописываю дабы иметь возможность сравнивать синтаксис c#, дельфи и java.
поэтому и 1.5 хватит
← →
Суслик © (2007-02-28 20:03) [32]
> [27] Сотрудник деканата (28.02.07 19:56)
> > Суслик © (28.02.07 19:35) [19]
>
> А почему не 1.6...?
да я так - чисто для себя, иногда пописываю дабы иметь возможность сравнивать синтаксис c#, дельфи и java.
поэтому и 1.5 хватит
← →
Ketmar © (2007-02-28 20:03) [33]> iZEN © (28.02.07 20:00) [29]
> Я же предупреждал, что пошаговая отладка в многопоточном
> приложении НЕ_РАБОТАЕТ.
чудесная, чудесная штука эта ваша жаба...
← →
iZEN © (2007-02-28 20:08) [34]
> Юрий Зотов © (28.02.07 19:57) [28]
> Но ведь значение константы отладчик показывает абсолютно
> правильно. Почему же, пока тупо не введешь ее промежуточное
> запоминание, имеем глюк?
javac все public static final инлайнит в байткод, который обращается к этим константам. (Кстати, такой же эффект наблюдается со строками, которые объявляют в интерфейсах -- в классах, реализующих такие инетрфейсы, строки вставляются в сам байткод класса. Так что объявление констант в интерфейсах -- ТАБУ).
← →
Ketmar © (2007-02-28 20:10) [35]ага. сеперлогичный и защищённый язык. класс.
← →
Ученик чародея © (2007-02-28 20:11) [36]
> Ketmar © (28.02.07 20:03) [33]
>
> > iZEN © (28.02.07 20:00) [29]
> > Я же предупреждал, что пошаговая отладка в многопоточном
> > приложении НЕ_РАБОТАЕТ.
> чудесная, чудесная штука эта ваша жаба...
Она работает, только с глюками в режиме отладки. Истинный программист должен писать код без единой ошибки и сразу.
← →
iZEN © (2007-02-28 20:12) [37]Вообще же, лучше посмотреть, что собой представляет .class-файл на самом деле (с помощью декомпилятора javap).
P.S.
Зачем пинать труп Java 5.0? Пора переходить на Java 6.0.
← →
iZEN © (2007-02-28 20:13) [38]
> Ketmar © (28.02.07 20:03) [33]
> чудесная, чудесная штука эта ваша жаба...
Нужно быть готовым ко всему! :))
← →
Anatoly Podgoretsky © (2007-02-28 20:14) [39]> iZEN (28.02.2007 20:12:37) [37]
Переходить или пинать Java 6.0.
← →
Суслик © (2007-02-28 20:15) [40]пора переходить на дельфи2007!
← →
Ketmar © (2007-02-28 20:18) [41]> iZEN © (28.02.07 20:13) [38]
> Нужно быть готовым ко всему! :))
да я давно готов жабу пристрелить. пусть только рядом пробежит...
← →
iZEN © (2007-02-28 20:31) [42]
> Ketmar © (28.02.07 20:18) [41]
>
> > iZEN © (28.02.07 20:13) [38]
> > Нужно быть готовым ко всему! :))
> да я давно готов жабу пристрелить. пусть только рядом пробежит.
> ..
С некоторых пор она не бегает (и уже не ползает). Она летает! :)
P.S.
Мне хочется отправить фтопку Python2.5 и XUL. Ну очень тормозно и глюкаво всё. Firefox столько памяти жрёт -- ужас.
← →
Ketmar © (2007-02-28 20:53) [43]> iZEN © (28.02.07 20:31) [42]
> Она летает! :)
угу. с крыши на асфальт.
> Мне хочется отправить фтопку Python2.5 и XUL
на здоровье. два <autocensored>.
← →
iZEN © (2007-02-28 21:06) [44]((Прошу прощения, не Python2.5, а Python2.4.))
← →
Игорь Шевченко © (2007-02-28 21:42) [45]Суслик © (28.02.07 20:15) [40]
> пора переходить на дельфи2007!
Целиком и полностью поддерживаю!
← →
Юрий Зотов © (2007-02-28 21:48) [46]> iZEN © (28.02.07 20:08) [34]
Да пусть он себе инлайнит что хочет, и куда хочет, это его личное дело.
Но когда обращение к значению константы напрямую и обращение к нему же через промежеточную переменную дают РАЗНЫЕ результаты - это стопроцентный глюк. Хоть 100 раз он заинлайнит - но он ОБЯЗАН сделать это 100 раз ОДИНАКОВО.
← →
Канадец (2007-02-28 22:22) [47]>Юрий Зотов © (28.02.07 21:48) [46]
Кстати всё логично получается.
Изменение статической константы в исходном классе не влечёт за собой изменение класса где она используется потому, что компилятор подставляет константное значение вместо ссылки на константу. С этим всё понятно. Отладчик берёт значение статической константы из класса непосредственно поэтому вы наблюдаете разные значения. С этим тоже всё понятно.
А вот когда вы объявляете локальную переменную, вы изменяете код класса где она используется, что в свою очередь ведёт к перекомпиляции и к подстановке нового значения. Поэтому всё красиво работает.
← →
Ketmar © (2007-02-28 23:31) [48]> Канадец (28.02.07 22:22) [47]
если компилятор заоптимизировался до полного маразма, то это баг разработчиков, а никак не пользователей.
заинлайнил? запомни, откуда, и перекомпилируй то, что надо, коли поменяли. не можешь? глючище. жаба, короче...
← →
Petr V. Abramov © (2007-02-28 23:46) [49]> Юрий Зотов © (28.02.07 18:23) [0]
да ладно, в Дельфе чтоль ни разу такого не было
но в общем и целом сочуствую.... терпи...
← →
Суслик © (2007-03-01 01:37) [50]
> Юрий Зотов © (28.02.07 21:48) [46]
делай полный билд, и все будет ок.
мне (в моем отсталом нетбинсе фор дот зеро) помогало.
← →
Германн © (2007-03-01 01:49) [51]
> Petr V. Abramov © (28.02.07 23:46) [49]
>
> > Юрий Зотов © (28.02.07 18:23) [0]
> да ладно, в Дельфе чтоль ни разу такого не было
А ты, Петь, можешь привести пример аналога (хотя бы приблизительного) в "Дэльфе?"
Степень "приблизительности" оценят в следущих постах :)
← →
Alex Konshin © (2007-03-01 01:54) [52]
> Ketmar © (28.02.07 23:31) [48]
>
> > Канадец (28.02.07 22:22) [47]
> если компилятор заоптимизировался до полного маразма, то
> это баг разработчиков, а никак не пользователей.
>
> заинлайнил? запомни, откуда, и перекомпилируй то, что надо,
> коли поменяли. не можешь? глючище. жаба, короче...
>
Причем тут Java?
Это глюк/feature Eclipse у которого, кстати, свой встроеный компилятор.
Кстати, а вы уже все позабыли, что в Delphi IDE перед отладкой крайне желательно перекомпилировать все из-за подобных же глюков? Или то, что позволено Delphi, не позволено Java?
Объективнее надо быть, друзья. :)
← →
Суслик © (2007-03-01 01:59) [53]не только объективней, но и ориентированнее!!!!!
-------
В дельфи тоже бывает разное - у меня были случай, когдя я довел оптимизатор до изменения функционала.
Вот (это мой репорт в QC)
1. Run this project{$o+}
program Project1;
uses
SysUtils, Windows;
type
TItem = record
private var Dummy: array[0..1111] of Integer;
public class function New(): TItem; static;
public procedure Change();
end;
class function TItem.New(): TItem;
begin
Result.Dummy[0] := 1;
end;
procedure TItem.Change();
begin
Dummy[0] := 2;
end;
procedure A(const Item: TItem);
begin
Item.Change();
end;
var
kItem: TItem;
kI: Integer;
begin
kItem := TItem.New();
kI := kItem.Dummy[0];
MessageBox(0, PChar(IntToStr(kI)), "before A() call", 0);
A(kItem);
kI := kItem.Dummy[0];
MessageBox(0, PChar(IntToStr(kI)), "after A() call", 0);
end.
2. See the behaviour
3. Run this project again with {$o-}
4. See the *different* behaviour: you must see the different content of "after A() call"
message box.
← →
Суслик © (2007-03-01 02:00) [54]Закрыли, кстити, репорт со словами - сам дурак
> The bug is in the test application, not the compiler. It
> iis unreasonable to expect the compiler to generate code
> that produces the same results with $o+ and $o- if the assumptions
> that you allow it to make (in this case that "procedure
> A(const Item:TItem)" does not change "Item") are incorrect
> due to a programming error.
PS
Полностью согласен с решением, кстати.
← →
DiamondShark © (2007-03-01 11:32) [55]
> Полностью согласен с решением, кстати.
А я не согласен.
Пятая дельфи в случае
type Z = record
A: integer;
end;
procedure Q(var a: Z);
begin
a.A := 1;
end;
procedure W(const a: Z);
begin
Q(a);
end;
Добросовестно ругалась "Constant object cannot be passed as var parameter"
От того, что в результате издевательств над синтаксисом у записей появились методы, объявление
public procedure Change();
не перестало быть в действительности
public procedure Change(var Self: TItem);
Что мешало здесь выдать точно такое же предупреждение?
Возражения рода: "А тогда бы появился гемор с вызовом методов записи откуда ни попадя!" не принимаются.
Во-первых, подобный гемор с простыми процедурами никого не напрягает, и помогает контролировать side effect.
Во-вторых, нефиг извращаться над синтаксисом, бездумно вводя абсолютно левые фичи.
А если уж извращаться, то по-чёрному. Например, ничего не мешает декларировать метод как свободный от side effect, например, так:
public const procedure Change();
что семантически эквивалентно
public procedure Change(const Self: TItem);
и всё замечательно проверяется на этапе компиляции.
Так что это не "сам дурак". Это борландцы -- негодяи и лентяи.
Испохабили язык, до конца не додумали, да ещё и отмазываются.
← →
Ketmar © (2007-03-01 11:36) [56]самое противное то, что ребята из FPC Team ведь ломанутся реализовывать весь тот идиотизм, что напридумывали в новых дельфях...
← →
Суслик © (2007-03-01 11:39) [57]
> [55] DiamondShark © (01.03.07 11:32)
А на это есть другой мой репорт. Когдя я согласился с решением сисопа о данном репорте, то я решил отрыть новый (примерно на твой похож). Репорт открыли, что будет - посмотрим.
------------------
Язык они испохабили, согласен.
Но они очень работают над тем, чтобы привести его в логичное состояние. Я верю, что у них это получится.
← →
Суслик © (2007-03-01 11:39) [58]Удалено модератором
Примечание: Дубль
← →
Суслик © (2007-03-01 11:39) [59]Удалено модератором
Примечание: Дубль
← →
Ученик чародея © (2007-03-01 11:50) [60]Удалено модератором
Примечание: Достал
← →
evvcom © (2007-03-01 12:13) [61]> [47] Канадец (28.02.07 22:22)
> А вот когда вы объявляете локальную переменную, вы изменяете
> код класса где она используется, что в свою очередь ведёт
> к перекомпиляции и к подстановке нового значения. Поэтому
> всё красиво работает.
Но в этом случае возврат к варианту без локальной переменной тоже должен начать работать правильно.
2 Юрий Зотов ©: а так тот же глюк или все ж начинает правильно работать?
← →
DiamondShark © (2007-03-01 12:42) [62]Забавная мысль по поводу.
Действительно хорошо было бы явно декларировать побочный эффект методов.
Т.е., к примеру, я как разработчег какого-нибудь базового класса могу написать:
public const function GetValue: Integer; virtual; abstract;
и быть спокоен, что никакому врагу не дозволено будет реализовать геттер с побочным эффектом.
Хотя, тут встаёт вопрос, что делать с полями-ссылками на объекты.
Компилятор запретит изменить саму ссылку. Но нет никакой возможности контролировать изменение экземпляра по ссылке.
:(
← →
Ketmar © (2007-03-01 12:44) [63]Дима, тут как по рукам не бей -- всё равно найдут, где сломать. головы чинить надо, а не синтаксис...
← →
iZEN © (2007-03-04 00:04) [64]Ну и напоследок полезная ссылка на материал о модели памяти в Java:
"Теория и практика Java: Исправление модели памяти Java, Часть 1"
http://www.ibm.com/developerworks/ru/library/j-jtp02244/index.html
← →
iZEN © (2007-03-04 00:10) [65]Недостатки оригинальной модели памяти Java
В то время, как модель памяти JMM, заданная в главе 17 спецификации Java Language Specification, была амбициозной попыткой определить единообразную, межплатформенную модель памяти, у нее есть несколько незаметных, но существенных недостатков. Семантика synchronized и volatile была довольно такой запутанной, настолько, что многие хорошо подготовленные разработчики предпочитали иногда игнорировать правила, потому что написание соответствующим образом синхронизированного кода под старой моделью памяти было затруднительно.
Старая модель памяти JMM допускала некоторые удивительные и сбивающие с толку вещи, например появление в полях final не тех величин, которые были установлены в конструкторе (что могло превратить неизменяемые объекты в изменяемые), а также неожиданные результаты при переупорядочивании операций с памятью. Это также мешало некоторым формам оптимизаций программ во время компилирования, которые в иных случаях эффективны. Если вы прочли какие-либо статьи о проблеме блокировки с двойной проверкой (см. Ресурсы), вы помните, насколько запутанной может быть операция по переупорядочиванию, и насколько незаметные, но серьезные проблемы могут проникнуть в ваш код, когда вы не выполняете синхронизацию должным образом (или активно пытаетесь избежать синхронизации). Хуже того, многие неправильно синхронизированные программы оказываются работают правильно в некоторых ситуациях, например, при при небольшой загрузке, на однопроцессорных системах, или на процессорах с более сильными моделями памяти, чем это требуется JMM.
Термин переупорядочивание используется для описания нескольких классов реальных и очевидных перераспределений операций с памятью:
* Компилятор может в качестве оптимизации свободно переупорядочивать определенные инструкции, если это не меняет семантику программы.
* Процессору позволяется исполнять операции не по порядку в некоторых обстоятельствах.
* Кэшу, как правило, позволяется выполнять обратную запись переменных в основную память не в том порядке, в котором они были записаны программой.
Любые из этих условий могут привести к тому, что с точки зрения другого потока операции могут происходить не в том порядке, как это задано программой, и независимо от источника переупорядочивания, все считается моделью памяти эквивалентным.
← →
Petr V. Abramov © (2007-03-04 00:16) [66]"в дворницкой стоял запах гниющего навоза, распространяемого новыми валенками Тихона. Старые валенки стояли в углу и воздуха тоже не озонировали"
12 стульев
← →
iZEN © (2007-03-04 01:50) [67]
> Petr V. Abramov © (04.03.07 00:16) [66]
Согласен. Сначала разложили грабли, замаскировали их, на них наступали, а потом радостно сообщили всем о том, где они лежат, огородив это место ленточкой. Ж))
Страницы: 1 2 вся ветка
Форум: "Прочее";
Текущий архив: 2007.03.25;
Скачать: [xml.tar.bz2];
Память: 0.65 MB
Время: 0.053 c