Встретив синтаксическую ошибку в Вашем коде, компилятор Visual J++ сообщает о ней, указывая, что приложение не удалось обновить. Список ошибок выводится в окне Task List среды программирования Visual J+ + .
Однако синтаксическими
ошибками дело, как правило, не ограничивается: в коде часто встречаются логические
ошибки, например бесконечные циклы. Справиться с ними поможет отладчик Visual
J+ + . О применении встроенного отладчика для отладки проектов Visual J+ + см.
раздел «Базовые процедуры отладки» далее в этой главе. Там Вы узнаете,
как устанавливать точки прерывания, пошагово выполнять код, наблюдать за значениями
переменных и многое другое. В состав электронной документации включены примеры,
которые помогут освоить методику отладки проектов различных типов. Как воспроизвести
эти примеры, описано в следующих разделах:
Отладчик
Visual J++ поддерживает большинство стандартных функций отладки исходного кода,
включая точки прерывания (обычные и условные), контрольные выражения, управление
потоками и обработку исключений. Кроме того, Вы можете пошагово выполнять код
(по одному оператору или методу), наблюдая за значениями переменных и свойств
Вряд ли можно дать какие-то общие рекомендации по отладке приложений или сформулировать
один подход на все случаи жизни. В принципе, отладка просто помогает понять,
как ведет себя приложение в процессе выполнения, а ее средства позволяют сделать
«моментальный снимок» текущего состояния приложения, в том числе:
Отладив несколько
приложений, Вы заметите, что некоторые процедуры отладки применимы практически
ко всем программам.
Ввод
аргументов командной строки
Если приложение,
которое Вы отлаживаете, требует аргументов в командной строке, их можно ввести
либо из командной строки, либо из среды программирования.
В следующей
процедуре поясняется, как использовать параметры раздела Custom на вкладке
Launch диалогового окна свойств проекта. Для доступа к диалоговому окну
свойств открытого проекта выберите соответствующую команду из меню Project.
Чтобы
ввести аргументы командной строки:
Примечание
В поле Arguments могут присутствовать и параметры, предлагаемые
по умолчанию. Если Вы по какой-то причине решите изменить их, сделайте сначала
это и только потом вводите дату.
Теперь Вы
готовы к отладке приложения. Один из способов начать ее — установить точки прерывания,
а потом запустить отладчик.
Эта панель
инструментов открывает доступ к часто используемым командам и окнам отладчика.
Чтобы
вывести на экран панель инструментов Debug:
Точка прерывания
— место в коде, где выполнение приостанавливается, что позволяет наблюдать за
поведением программы, значениями ее переменных и в некоторых случаях — регистров.
Кроме того, в этот момент можно внести изменения в код, а затем продолжить (или
завершить) его выполнение. В этом разделе поясняется, как устанавливать точки
прерывания.
Установка
точек прерывания до запуска отладчика
После создания
и сборки проекта Visual J++ в его коде можно расставить точки прерывания. Если
поведение программы свидетельствует о наличии ошибки, точки прерывания позволяют
временно остановить ее выполнение там, где, как Вы подозреваете, кроется источник
проблемы.
Чтобы
установить точку прерывания и запустить отладчик:
На левом поле окна
редактора появится красный кружочек, обозначающий, что в данном операторе
находится точка прерывания.
Когда
программа находится в режиме прерывания, Вы можете:
Чтобы
возобновить выполнение программы под управлением отладчика:
— или —
Нажмите клавишу F5,
чтобы продолжить выполнение программы до следующей точки прерывания.
— или —
Нажмите клавишу F11,
чтобы выполнить следующий оператор. Чтобы завершить отладку:
Подробнее
о завершении сеанса отладки см. раздел «Ending a Debugging Session»
в электронной документации Visual Studio.
Установка
точек прерывания из диалогового окна Breakpoints
До сих пор
Вы добавляли и удаляли точки прерывания, выбирая команды из контекстного меню.
Оно же позволяет активизировать и отключать точки прерывания, а также изменять
их свойства. Но диалоговое окно Breakpoints, предоставляемое отладчиком,
обеспечивает больший контроль над точками прерывания.
Анализ
информации в отладочных окнах
Здесь описывается,
для чего предназначено каждое отладочное окно и как им пользоваться.
Окно Auto
В этом окне
отображаются значения всех переменных в области видимости выполняемых на данный
момент методов. В отличие от окна Locals, где показываются переменные для одного
потока, окно Auto сообщает о переменных для всех потоков. Это окно, в частности,
позволяет отслеживать изменения в значениях переменных, вызванные выполнением
кода в другом потоке. Переменная доступна (и Вы можете наблюдать за ее значениями),
пока не выйдет за область видимости. После этого она удаляется из окна Auto.
Содержимое
окна Auto обновляется, только когда программа приостановлена — например, Вы
добавляете новую контрольную переменную, изменяете значение какой-либо переменной-члена
или переключаете формат отображения значений между десятичным и шестнадцатерич-ным
(через контекстное меню). Значения переменных, изменившихся с момента последнего
прерывания программы, выделяются красным цветом.
Чтобы
открыть окно Auto:
— или —
Нажмите клавиши Ctrl+Alt+A.
- или — Щелкните кнопку Auto на панели инструментов Debug.
Чтобы
скопировать переменную из окна Auto в другое окно:
Чтобы
изменить значение переменной:
Чтобы
вывести или скрыть переменные и элементы массива класса:
Подробнее
о том, как работать с этим окном и просматривать переменные и элементы массива
класса, см. раздел «Комбинации клавиш для работы с окнами Auto, Locals
и Watch» далее в этой главе. Подробнее об окне Auto см. раздел «Viewing
Variables in the Auto Window» в электронной документации Visual Studio.
Окно Locals
В этом окне
перечисляются переменные классов (переменные-члены) и показываются их значения
для каждого метода в текущем-кадре стека. По мере того как программа переходит
из одного метода в другой, содержимое окна Locals изменяется, отображая локальные
переменные текущего метода.
Для каждой
переменной класса в окне Locals предусмотрены поля Name, Value и Туре. Значение
переменной появляется в этом окне сразу после ее объявления в программе. Если
переменная находится вне области видимости, когда Вы просматриваете окно Locals,
в поле Value выводится соответствующее сообщение. Это значит, что просмотр
значения данной переменной невозможен, пока Вы не выполните еще какую-то часть
кода. Содержимое окна Locals обновляется, только когда программа приостановлена.
Значения переменных, изменившихся с момента последнего прерывания программы,
выделяются красным цветом.
Чтобы
открыть окно Locals:
— или —
Нажмите клавиши Ctrl+Alt+L.
— или —
Чтобы
сменить класс, информация о котором отображается в окне Locals:
Примечание
Определив в программе более одного класса, Вы, вероятно, захотите
понаблюдать за значениями переменных во всех этих классах. В окне Locals всегда
показываются переменные-члены только того класса, в котором присутствует стартовая
точка Вашей программы — метод main или init. Если при пошаговом выполнении программы
или остановке ее на точке прерывания Вы попали в другой класс, можете просмотреть
значения его переменных-членов, выбрав имя этого класса из списка в верхней
части окна Locals.
Чтобы
скопировать переменную из окна Locals в другое окно:
Чтобы
изменить значение переменной:
Чтобы
вывести или скрыть переменные и элементы массива класса:
Подробнее
о том, как работать с этим окном и просматривать переменные и элементы массива
класса, см. раздел «Комбинации клавиш для работы с окнами Auto, Locals
и Watch» далее в этой главе. Подробнее об окне Locals см. раздел «Viewing
Local Variables in the Locals Window» в электронной документации Visual
Studio.
Окно Watch
Это окно
позволяет наблюдать за значениями переменных, свойств и выражений при выполнении
программы. Немедленно выявить источник проблем «с точностью» до
конкретного оператора удается нечасто. И здесь помогает окно Watch, где можно
проверить, как изменяются значения переменных и выражений при выполнении кода.
Среда программирования автоматически отслеживает указанные Вами контрольные
выражения. Когда программа приостанавливается, они появляются в окне Watch и
Вы можете увидеть их значения.
Чтобы
открыть окно Watch:
— или —
Нажмите клавиши Ctrl+Alt+W.
— или —
Чтобы
добавить контрольное выражение на этапе разработки или в режиме прерывания:
Чтобы
изменить значение переменной:
Чтобы
вывести или скрыть переменные и элементы массива класса:
Подробнее
о том, как работать с этим окном и просматривать переменные и элементы массива
класса, см. раздел «Комбинации клавиш для работы с окнами Auto, Locals
и Watch» далее в этой главе. Подробнее об окне Watch см. раздел «Inspecting
Variables and Properties with the Watch Window» в электронной документации
Visual Studio.
Комбинации
клавиш для работы с окнами Auto, Locals и Watch
Работая с
окнами Auto, Locals и Watch, можно использовать следующие комбинации клавиш.
Действие |
Клавиша |
||
Развертывание списка Свертывание списка Развертывание/свертывание списка Перемещение вверх по элементам списка Перемещение вниз по элементам списка Перемещение по спискам вверх Перемещение
по спискам вниз |
Стрелка вправо Стрелка влево Enter Стрелка вверх Стрелка вниз Стрелка влево Стрелка вправо |
||
Окно Immediate
Это окно
позволяет просматривать и изменять значения. Здесь можно вычислить любое выражение
или переменную, увидеть, какое значение возвращает объект, или выяснить, к какому
результату приводят набираемые Вами команды (они должны быть на том же языке,
что и выполняемый код).
Когда программа
приостановлена, можно активизировать окно Immediate для анализа текущих значений.
Область видимости переменных и объектов в окне Immediate определяется формой
или классом, активным на данный момент.
Чтобы
открыть окно Immediate:
— или —
Нажмите клавиши Ctrl+Alt
+ I.
— или —
Чтобы
добавить выражение или переменную в окно Immediate:
Чтобы
оценить значение выражения или переменной в окне Immediate:
Примечание
Для просмотра переменных или выражений, в состав которых входит код
сценария, ставьте перед их именами вопросительный знак.
Если Вы выбрали
переменную, окно Immediate сообщит ее текущее значение, а если Вы выбрали выражение
— результат его оценки.
Чтобы
повторно выполнить уже введенный оператор:
Совет
Не нажимайте клавишу Enter, если курсор находится не на том операторе, который
Вы хотите выполнить.
Подробнее
об окне Immediate см. раздел «Executing Commands and Evaluating Expressions
in the Immediate Window» в электронной документации Visual Studio.
Окно Threads
При отладке
многопоточных приложений окно Threads позволяет сменить выполняемый в данный
момент поток и просмотреть список потоков любого процесса, связанного с Вашим
приложением. При смене потока в этом окне соответственно изменяется содержимое
остальных отладочных окон. Подробнее на эту тему см. разделы «Threads
Window» и «Controlling Threads» в электронной документации
Visual Studio.
Открытие
отладочного окна Threads
Чтобы
открыть окно Threads:
— или —
Нажмите клавиши Ctrl
+ Alt + Т.
— или —
Наблюдение
за потоком в окне Threads
Здесь используется
приложение-пример, метод main которого создает два потока и направляет вывод
в консольное окно JView. Исходный код этого приложения см. в разделе «Пример
многопоточного приложения» далее в этой главе. Если Вы хотите воспроизвести
операции, рассматриваемые в данном разделе, создайте проект этого приложения
прямо сейчас.
Чтобы
наблюдать за поведением потока:
System.out.println("I
Like Coffee" + " " + i);
System.out.println("I
Like Tea" + " " + i);
Coffee m_Coffee = new
Coffee(); //создается объект Coffee
В окне Threads появится
дополнительная информация об именах, текущем участке кода и состоянии трех
потоков Вашего приложения: main, Thread-0 и Thread-1. Желтая стрелка
указывает, какой поток выполняется в данный момент, — Thread-О метода
Coffee.run. Заметьте, что поток main сейчас не выполняется, так как он передал
управление потокам классов Coffee и Tea.
Примечание
Хотя здесь предполагается, что первым выполняется поток класса Coffee,
это не всегда так. Операционная система сама определяет порядок обработки потоков
в приложении -кроме тех случаев, когда в коде присутствуют операторы, задающие
условия создания и запуска нового потока.
I Like Tea 0
I Like Coffee 9
— или —
I Like Tea 9
После уничтожения
потока исчезает и информация о нем (в окне Threads).
Наблюдая
за каждым из потоков приложения, Вы сможете выявить тот, который ведет себя
не так, как ожидалось. Как изолировать поток, приостановив остальные потоки,
см. следующий раздел.
Приостановка
и возобновление потоков из окна Threads
Здесь используется
приложение-пример, метод main которого создаст два потока и направляет вывод
в консольное окно JView. Исходный код этого приложения см. в разделе «Пример
многопоточного приложения» далее в этой главе. Если Вы хотите воспроизвести
операции, рассматриваемые в данном разделе, создайте проект этого приложения
прямо сейчас.
Чтобы
приостановить поток:
System.out.println("I
Like Coffee" + " " + i);
в классе Tea на операторе:
System.out.println("I
Like Tea" + " " + i);
Примечание
Операционная система сама определяет порядок обработки потоков в
приложении — кроме тех случаев, когда в коде присутствуют операторы, задающие
условия создания и запуска нового потока.
Обратите внимание:
значение счетчика Suspension, Count потока Thread-1 изменилось
с 0 на 1.
Если Вы используете
приложение-пример, в консольное окно JView направляется вывод всех потоков,
кроме приостановленного. При отладке многопоточного приложения в какой-то момент
может понадобиться возобновить приостановленный поток. Делается это так, как
описано в следующей процедуре.
Примечание
Эта процедура требует предварительно:
Чтобы
возобновить приостановленный поток:
Обратите
внимание: значение счетчика Suspension Count потока Thread-1 изменилось
с 1 на 0.
Окно Call
Stack
В окне Call
Stack отображается список активных процедур или кадров стека для потока, выполняемого
в данный момент. В этом контексте активными считаются незавершенные процедуры.
Чтобы
открыть окно Call Stack:
— или —
Нажмите клавиши Ctrl+Alt
+ С.
— или —
Щелкните кнопку Call Stack на панели инструментов Debug.
Чтобы сменить активный
поток из окна Call Stack:
О специфических
элементах этого окна см. раздел «Viewing the Call Stack» в электронной
документации Visual Studio.
Окно Running
Documents
В окне Running
Documents показывается список документов, загруженных на данный момент. Например,
если в Вашем проекте имеется набор HTML-фреймов, в окне Running Documents отображается
список страниц, уже загруженных браузером.
Чтобы
открыть окно Running Documents:
— или —
Нажмите клавиши Ctrl+Alt
+ R.
— или —
Щелкните кнопку Running Documents на панели инструментов Debug.
Чтобы открыть
документ из окна Running Documents:
Приложение-пример,
используемое в этой процедуре, преобразует вводимую в командной строке календарную
дату в юлианскую. Оно собрано по процедуре, описанной в разделе «Создание
консольного приложения» главы 1 «Создание проектов». Если
Вы хотите воспроизвести данный пример, создайте проект консольного приложения
прямо сейчас.
Сценарий
этой процедуры таков: Вы вводите исходную дату, останавливаете программу в точке
прерывания и — с помощью отладочных окон — просматриваете значения некоторых
переменных своей программы. К этому моменту Вы уже представляете, где кроется
источник проблемы, но хотите пошагово выполнить ряд операторов, чтобы получше
разобраться в происходящем. Как это сделать, поясняет следующая процедура.
Чтобы
пошагово выполнять код в режиме прерывания:
for(int nCount=1; nCount
< m_nMonth; nCount++)
Желтая стрелка на
левом поле указывает оператор, который будет выполнен следующим.
Подробнее
о пошаговом выполнении программы в отладчике см. раздел «Stepping Through
Code to Trace Execution» в электронной документации Visual Studio.
Чтобы
завершить сеанс отладки:
В этом разделе
Вы познакомитесь с принципами отладки приложений, созданных на базе Windows
Foundation Classes for Java (WFC).
Примечание
В следующем сценарии используется приложение, собранное в разделе «Создание
Windows-приложения с применением WFC» главы 1 «Создание проектов».
Если Вы хотите воспроизвести предлагаемый сценарий, создайте такое приложение
прямо сейчас.
Приложение
в данном сценарии преобразует календарную дату в юлианскую. Вы вводите дату,
ставите точку прерывания и начинаете отладку, наблюдая за значениями переменных
классов в отладочных окнах. Хотя здесь используется код, преобразующий даты,
Вы можете проделать все операции с кодом своей программы.
Введя календарную
дату для преобразования в юлианскую, запустите сеанс отладки (см. раздел «Установка
точек прерывания до запуска отладчика» ранее в этой главе).
Достигнув
точки прерывания, программа приостановится — исследуйте значения переменных
классов в окнах Auto, Locals, Watch и Immediate. Это поможет понять, что происходило
в программе до момента ее прерывания.
Изучив, текущее
состояние программы, можете добавить другую точку прерывания и продолжить пошаговое
выполнение кода. Сценарий отладки WFC-приложения на этом закончен. Подробнее
о применении отладочных средств см. раздел «Базовые процедуры отладки»
ранее в этой главе.
Отладка
консольного приложения
В этом разделе
Вы познакомитесь с отладкой консольных Java-приложений.
Примечание
В следующем сценарии используется приложение, собранное в разделе
«Создание консольного приложения» главы 1 «Создание проектов».
Если Вы хотите воспроизвести предлагаемый сценарий, создайте такое приложение
прямо сейчас.
Приложение
в данном сценарии преобразует календарную дату в юлианскую. Вы вводите дату,
ставите точку прерывания и приступаете к отладке, наблюдая за значениями переменных
классов в отладочных окнах. Хотя здесь используется код, преобразующий даты,
Вы можете проделать все операции с кодом своей программы. Перед запуском этого
приложения надо сначала передать ему из командной строки календарную дату, преобразуемую
в юлианскую. Как ввести аргументы командной строки с вкладки Launch диалогового
окна свойств проекта, см. раздел «Ввод аргументов командной строки»
ранее в этой главе. Введя аргументы, откройте сеанс отладки (см. раздел «Установка
точек прерывания до запуска отладчика» ранее в этой главе). Достигнув
точки прерывания, программа приостановится — исследуйте значения переменных
классов в окнах Auto, Locals, Watch и Immediate. Это поможет понять, что происходило
в программе до момента ее прерывания.
Изучив текущее
состояние программы, можете добавить другую точку прерывания и продолжить пошаговое
выполнение кода. Сценарий отладки консольного приложения на этом закончен. Подробнее
о применении отладочных средств см. раздел «Базовые процедуры отладки»
ранее в этой главе.
Отладка
многопоточного приложения
Процесс —
это виртуальное адресное пространство, код, данные и системные ресурсы приложения,
а поток — код, последовательно выполняемый в процессе. Процессор обрабатывает
именно потоки, а не процессы, и поэтому любое 32-разрядное приложение состоит
минимум из одного процесса и одного потока. До того как появилось понятие «мно-гопоточность»,
приложения состояли из единственного потока. Если Вы заметили, что Ваше многопоточное
приложение или компонент работает некорректно, то, чтобы выявить источник проблем,
Вам, возможно, понадобится отладить код, выполняемый в конкретном потоке. Следующие
процедуры описывают, как отлаживать многопоточные приложения, используя окно
Threads в сочетании с другими отладочными окнами и средствами.
Если у Вас
нет многопоточного приложения, но Вы все же хотите воспроизвести предлагаемые
процедуры отладки, создайте сначала приложение, представленное в следующем разделе.
Пример
многопоточного приложения
Здесь создается
консольное приложение, порождающее два потока. Программа состоит из трех классов:
Classl, Coffee и Tea. Classl содержит метод main и код, запускающий два потока
для выполнения кода классов Coffee и Tea.
Чтобы
создать многопоточное консольное приложение:
Чтобы
добавить в файл Class1.java классы Coffee и Tea:
Coffee m_Coffee = "new Coffee(); // создается объект
Coffee m_Coffee.start();
// создается поток для объекта Coffee
new Tea().start(); //
создается объект Tea и его поток
Код классов
Coffee и Tea
Приведенный
ниже фрагмент кода собственно и создает многопоточный процесс. Определенные
здесь классы Coffee и Tea расширяют класс Thread, что позволяет выполнять их
в отдельных потоках.
class Coffee
extends Thread {
public void
run() {
for(int i =
0; i < 10; i++) {
System.out.println("I
Like Coffee" + " " + i); yield(); } } }
class Tea extends
Thread {
public void
run()
{
for(int i =
0; i < 10; i++)
{
System.out.println("I
Like Tea" + " " + i); yield(); } } }
Отладка
многопроцессного приложения
Как уже говорилось,
процесс — это виртуальное адресное пространство, код, данные и системные ресурсы
приложения, а поток — код, последовательно выполняемый в процессе. Процессор
обрабатывает именно потоки, а не процессы, и поэтому любое 32-разрядное приложение
состоит минимум из одного процесса и одного потока. До того как появилось понятие
«многопоточность», приложения состояли из единственного потока.
Процессы взаимодействуют между собой посредством сообщений, передавая информацию
друг другу по механизму RFC (Remote Procedure Call). При этом безразлично, из
какого процесса приходит вызов — выполняемого на удаленной или на той же машине.
При отладке приложения, требующего для выполнения нескольких процессов, вероятно,
придется наблюдать за поведением всех процессов. Следующая процедура поясняет,
как выбирать процесс при отладке приложения.
Чтобы
выбрать процесс из окна Threads:
Выбрав нужный
процесс, следуйте инструкциям из раздела «Базовые процедуры отладки»;
при этом Вы можете:
СОМ-сервер
— это DLL- или ЕХЕ-файл, реализующий один или несколько классов, которые в свою
очередь реализуют один или несколько интерфейсов. СОМ-интерфейс представляет
собой группу семантически связанных функций, обеспечивающих доступ к определенной
функциональности объекта.
Отладка СОМ-сервера
отличается от отладки исполняемого файла или апплета главным образом потому,
что СОМ-сервер не предназначен для автономного
выполнения — он предоставляет сервис клиентам, каковыми могут быть исполняемые
файлы, ASP (Active Server Pages) или другие DLL.
Поэтому отладка
СОМ-сервера начинается, как правило, с загрузки его проекта в среду Visual J++,
которую затем конфигурируют для запуска своего отладочндго клиента. Потом расставляют
точки прерывания в коде объекта, чтобы после запуска отладочного клиента приостановить
код объекта в заданном месте. Прервав выполнение кода своего СОМ-сервера, действуйте
так же, как и при отладке обычного приложения или апплета.
Конкретный
подход к отладке сервера определяется в основном двумя факторами: типом отладочного
клиента, обращающегося к серверу, и средой, на которую рассчитан сервер.
Здесь поясняются
три подхода к отладке СОМ-сервера — различие между ними заключается в типах
применяемых отладочных клиентов.
Использование
ASP в качестве отладочного клиента
Прежде чем
приступить к отладке серверного компонента:
Подготовка
среды для отладки серверного Java-компонента
Чтобы
подготовить среду для отладки серверного Java-компонента:
В окне браузера
появится содержимое Вашей ASP-страницы. Сконфигурировав IIS и среду Visual J+
+ , Вы готовы к отладке серверного Java-компонента.
Запуск
сеанса отладки серверного Java-компонента
Чтобы
отладить серверный Java-компонент:
Код сценария
вызовет Ваш компонент, выполнение которого приостановится в заданной Вами точке
прерывания.
Теперь среда
программирования и Ваш проект готовы к отладке компонента обычными средствами.
Применение
исполняемого файла в качестве отладочного клиента
В проекте
серверного компонента можно указать исполняемый файл, который будет служить
отладочным клиентом.
Чтобы
сконфигурировать исполняемый клиентский файл:
Когда отладчик
Visual J+ + приостановит выполнение кода компонента в заданной точке прерывания,
Вы сможете воспользоваться командами Step Over, Step Into и Step Out меню
Debug.
Использование
Microsoft Transaction Server (MTS)
Если разработанный
Вами компонент должен поддерживать MTS-тран-закции, для его отладки понадобится
как MTS, так и исполняемый файл.
Чтобы
сконфигурировать отладку MTS-компонента:
Запустите свой апплет в окне JView или Internet Explorer и действуйте так, как описано в разделе «Базовые процедуры отладки» ранее в этой главе.
1. Электромагнитная волна (в религиозной терминологии релятивизма - "свет") имеет строго постоянную скорость 300 тыс.км/с, абсурдно не отсчитываемую ни от чего. Реально ЭМ-волны имеют разную скорость в веществе (например, ~200 тыс км/с в стекле и ~3 млн. км/с в поверхностных слоях металлов, разную скорость в эфире (см. статью "Температура эфира и красные смещения"), разную скорость для разных частот (см. статью "О скорости ЭМ-волн")
2. В релятивизме "свет" есть мифическое явление само по себе, а не физическая волна, являющаяся волнением определенной физической среды. Релятивистский "свет" - это волнение ничего в ничем. У него нет среды-носителя колебаний.
3. В релятивизме возможны манипуляции со временем (замедление), поэтому там нарушаются основополагающие для любой науки принцип причинности и принцип строгой логичности. В релятивизме при скорости света время останавливается (поэтому в нем абсурдно говорить о частоте фотона). В релятивизме возможны такие насилия над разумом, как утверждение о взаимном превышении возраста близнецов, движущихся с субсветовой скоростью, и прочие издевательства над логикой, присущие любой религии.
4. В гравитационном релятивизме (ОТО) вопреки наблюдаемым фактам утверждается об угловом отклонении ЭМ-волн в пустом пространстве под действием гравитации. Однако астрономам известно, что свет от затменных двойных звезд не подвержен такому отклонению, а те "подтверждающие теорию Эйнштейна факты", которые якобы наблюдались А. Эддингтоном в 1919 году в отношении Солнца, являются фальсификацией. Подробнее читайте в FAQ по эфирной физике.