Компиляция Java - есть ли способ сказать компилятору игнорировать части моего кода?

В основном вы используете реквизиты для отправки информации от ребенка и родителя.

Добавляя все замечательные ответы, позвольте мне привести простой пример, объясняющий передачу значений от дочернего к родительскому компоненту в React

App.js

class App extends React.Component {
      constructor(){
            super();
            this.handleFilterUpdate = this.handleFilterUpdate.bind(this);
            this.state={name:'igi'}
      }
      handleFilterUpdate(filterValue) {
            this.setState({
                  name: filterValue
            });
      }
   render() {
      return (
        <div>
            <Header change={this.handleFilterUpdate} name={this.state.name} />
            <p>{this.state.name}</p>
        </div>
      );
   }
}

Header.js

class Header extends React.Component {
      constructor(){
            super();
            this.state={
                  names: 'jessy'
            }
      }
      Change(event) {

      // this.props.change(this.state.names);
      this.props.change('jessy');
  }

   render() {
      return (
       <button onClick={this.Change.bind(this)}>click</button>

      );
   }
}

Main.js

import React from 'react';
import ReactDOM from 'react-dom';

import App from './App.jsx';

ReactDOM.render(<App />, document.getElementById('app'));

То есть, теперь вы можете передавать значения с вашего клиента на сервер.

Take посмотрите на функцию «Изменить» в Header.js

Change(event) {
      // this.props.change(this.state.names);
      this.props.change('jessy');
  }

. Так вы вставляете значения в реквизиты с клиента на сервер

10
задан Merv 16 September 2008 в 16:20
поделиться

14 ответов

Предположение, что классы имеют схожую функциональность с 1,5 по сравнению с 6,0 различиями в реализации, Вы могли объединить их в один класс. Затем не редактируя источник для комментирования/некомментирования можно полагаться на оптимизацию, которую всегда делает компилятор. Если, если выражение всегда является ложью, кодом в, если оператор не будет включен в компиляцию.

Можно сделать статическую переменную в одном из классов для определения, какую версию Вы хотите выполнить:

public static final boolean COMPILED_IN_JAVA_6 = false;

И затем имейте проверку пострадавших классов, что статическая переменная и поместила различные разделы кода в простом если оператор

if (VersionUtil.COMPILED_IN_JAVA_6) {
  // Java 6 stuff goes here
} else {
  // Java 1.5 stuff goes here
}

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

4
ответ дан 3 December 2019 в 18:02
поделиться

Можно использовать API Reflection. поместите все свои 1,5 кода в один класс и 1,6 API в другом. В Вашем скрипте Ant создают две цели один для 1,5, который не скомпилирует 1,6 класса и один для 1,6, который не скомпилирует класс для 1,5. в Вашем коде проверяют Вашу версию Java и загружают соответствующий класс с помощью отражения, тот путь javac не будет жаловаться на пропавших без вести функций. Это - то, как я могу скомпилировать свой MRJ (Время выполнения Mac для Java) приложения на окнах.

0
ответ дан 3 December 2019 в 18:02
поделиться

Простое решение могло быть:

  • Поместите расходящиеся классы за пределами своего нормального пути к классу.
  • Запишите простой пользовательский classloader и установите его в основном как Ваше значение по умолчанию.
  • Для всех классов кроме 5/6 cassloader может подчиниться своему родителю (нормальная система classloader)
  • Для 5/6 (который должен быть единственными, которые не могут быть найдены родителем) он может решить, чтобы использовать через 'os.name' свойство или одно собственное.
0
ответ дан 3 December 2019 в 18:02
поделиться

Общедоступное статическое упомянутое выше конечное решение обладает одним дополнительным преимуществом, которое автор не упоминал - насколько я понимаю, компилятор распознает его во время компиляции и скомпилирует любой код, который является в, если оператор, который относится к той последней переменной.

Таким образом, я думаю, что это - точное решение, Вы искали.

0
ответ дан 3 December 2019 в 18:02
поделиться

Можно получить условную компиляцию, но не очень приятно - javac проигнорирует недостижимый код. Таким образом при структурировании кода правильно можно заставить компилятор игнорировать части кода. Для использования этого правильно необходимо было бы также передать корректные аргументы javac, таким образом, он не сообщает о недостижимом коде как об ошибках и отказывается компилировать :-)

0
ответ дан 3 December 2019 в 18:02
поделиться

Едва ли, но существуют обходные решения. См. http://forums.sun.com/thread.jspa?threadID=154106&messageID=447625

Тем не менее необходимо придерживаться, по крайней мере, наличия одной версии файла для Java 5 и один для Java 6, и включать их через сборку или сделать как соответствующие. Засовывание всего этого в одном большом файле и попытка заставить компилятор для 5 игнорировать материал, который это не понимает, не являются хорошим решением.

HTH

- nikki-

1
ответ дан 3 December 2019 в 18:02
поделиться

В Java нет никакого предварительного компилятора. Таким образом, никакой способ сделать #ifdef как в C. Сценарии сборки были бы лучшим способом.

0
ответ дан 3 December 2019 в 18:02
поделиться

Я думаю, что лучший подход здесь должен, вероятно, использовать сценарии сборки. У Вас может быть весь свой код в одном месте, и путем выбора, какие файлы включать, и который не можно включать, можно выбрать что версия кода скомпилировать. Обратите внимание, что это не может помочь при необходимости в управлении с более прекрасными зернами, чем на файл.

4
ответ дан 3 December 2019 в 18:02
поделиться

Это зависит, на каком Java 6 функций Вы хотите использовать. Для простой вещи как добавляющие сортировщики строки к JTables можно на самом деле протестировать во времени выполнения:

private static final double javaVersion =
         Double.parseDouble(System.getProperty("java.version").substring(0, 3));
private static final boolean supportsRowSorter =
         (javaVersion >= 1.6);

//...

if (supportsRowSorter) {
    myTable.setAutoCreateRowSorter(true);
} else {
    // not supported
}

Этот код должен быть скомпилирован с Java 6, но может быть выполнен с любой версией (ни на какие новые классы не ссылаются).

Править: чтобы быть более корректным, это будет работать с любой версией с тех пор 1.3 (согласно этой странице).

1
ответ дан 3 December 2019 в 18:02
поделиться

Можно, вероятно, осуществить рефакторинг код так, чтобы условная компиляция действительно не была необходима, просто условное выражение classloading. Что-то вроде этого:

public interface Opener{

public void open(File f);

 public static class Util{
        public Opener getOpener(){
          if(System.getProperty("java.version").beginsWith("1.5")){
           return new Java5Opener();
          }
          try{ 
            return new Java6Opener();
           }catch(Throwable t){
            return new Java5Opener();
           }
        }
 }

}

Это могло быть большим усилием в зависимости от того, сколько определенных для версии частей кода Вы имеете.

3
ответ дан 3 December 2019 в 18:02
поделиться

Можно сделать всю компиляцию исключительно на Java6 и затем использовать System.getProperty("java.version") для условного выполнения или Java5 или пути выполнения кода Java6.

У Вас может быть Java6-только код в классе, и класс будет хорошо работать на Java5, пока Java6-единственный путь выполнения кода не выполняется.

Это - прием, который используется для записи апплетов, которые будут работать на древнем MSJVM полностью до совершенно нового Плагина Java JVMs.

1
ответ дан 3 December 2019 в 18:02
поделиться

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

Решение легко. Выйдите из дела пострадавшие классы в два отдельных, независимых проекта - удостоверяются, что имена пакета являются тем же и просто компилируют в банки, которые можно затем использовать в основном проекте. Если Вы сохраняете имена пакета тем же и сигнатурами методов то же, никакие проблемы - просто не отбрасывают, какой бы ни версия банки Вам нужно в Ваш сценарий развертывания. Я предположил бы, что Вы запускаете отдельные скрипты сборки или имеете отдельные цели в том же сценарии - муравей и знаток могут и легко обработать условно файлы захвата и копирование их.

5
ответ дан 3 December 2019 в 18:02
поделиться

Это заставит всех пуристов Java съежиться (который является забавой, heh heh), но я использовал бы препроцессор C, поместил бы #ifdefs в мой источник. Make-файл, rakefile, или безотносительно средств управления Ваша сборка, должен был бы выполнить cpp для создания временного файла файлами для питания компилятора. Я понятия не имею, мог ли муравей быть заставлен сделать это.

В то время как stackoverflow похож, это будет место для всех ответов, Вы могли wehn ничей взгляд уходить на на http://www.javaranch.com для мудрости Java. Я предполагаю, что с этим вопросом имели дело там, пролил давным-давно.

1
ответ дан 3 December 2019 в 18:02
поделиться

Сохраните один "основной" исходный корень, который создает под JDK 5. Добавьте второй параллельный исходный корень, который должен создать под JDK 6 или выше. (Не должно быть никакого перекрытия, т.е. никаких классов, существующих в обоих.) Используют интерфейс для определения точки входа между этими двумя и крошечного бита отражения.

Например:

---%<--- main/RandomClass.java
// ...
if (...is JDK 6+...) {
    try {
        JDK6Interface i = (JDK6Interface)
            Class.forName("JDK6Impl").newInstance();
        i.browseDesktop(...);
    } catch (Exception x) {
        // fall back...
    }
}
---%<--- main/JDK6Interface.java
public interface JDK6Interface {
    void browseDesktop(URI uri);
}
---%<--- jdk6/JDK6Impl.java
public class JDK6Impl implements JDK6Interface {
    public void browseDesktop(URI uri) {
        java.awt.Desktop.getDesktop().browse(uri);
    }
}
---%<---

Вы могли настроить их как отдельные проекты в IDE с помощью другого JDKs и т.д. Дело в том, что основной корень может быть скомпилирован независимо, и очень ясно, что можно использовать, в котором корне, тогда как при попытке скомпилировать различные части единственного корня отдельно, слишком легко случайно "пропустить" использование JDK 6 в неправильные файлы.

Вместо того, чтобы использовать Class.forName как это, можно также использовать некоторую сервисную систему регистрации - java.util. ServiceLoader (если основной мог бы использовать JDK 6 и Вы хотели дополнительную поддержку JDK 7!), Поиск NetBeans, Spring, и т.д. и т.д.

Та же техника может использоваться для создания поддержки дополнительной библиотеки, а не более нового JDK.

2
ответ дан 3 December 2019 в 18:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: