Действительно ли статическое метапрограммирование возможно в Java?

Исключение нулевого указателя - это индикатор того, что вы используете объект, не инициализируя его.

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

public class Student {

    private int id;

    public int getId() {
        return this.id;
    }

    public setId(int newId) {
        this.id = newId;
    }
}

Приведенный ниже код дает вам исключение с нулевым указателем.

public class School {

    Student obj_Student;

    public School() {
        try {
            obj_Student.getId();
        }
        catch(Exception e) {
            System.out.println("Null Pointer ");
        }
    }
}

Поскольку вы используете Obj_Student, но вы забыли инициализировать его, как в правильном коде, показанном ниже:

public class School {

    Student obj_Student;

    public School() {
        try {
            obj_Student = new Student();
            obj_Student.setId(12);
            obj_Student.getId();
        }
        catch(Exception e) {
            System.out.println("Null Pointer ");
        }
    }
}
36
задан Community 23 May 2017 в 12:25
поделиться

7 ответов

Короткий ответ

Этому вопросу почти больше чем 10 лет, но я все еще пропускаю один ответ на это. И это: да , но не , потому что из дженериков и примечания вполне то же как C++.

С Java 6, мы имеем сменная аннотация, обрабатывающая api. Статическое метапрограммирование (как Вы уже заявили в своем вопросе)

выполнение программы времени компиляции

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

сменную аннотацию, обрабатывающую API, называет компилятор, прямо после того, как .java файлы читаются, но прежде чем компилятор пишет байт-код в .class файлы. (У меня был один источник для этого, но я не могу больше находить его.. возможно, кто-то может помочь мне здесь?).

Это позволяет Вам, чтобы сделать логику во время компиляции с чистым кодом Java. Однако мир, в котором Вы кодируете, очень отличается. Не специфически плохо или что-либо, просто отличающееся. Классы, которые Вы, еще анализируете не существуют, и Вы работаете над метаданными классов. Но компилятор запущен в JVM, что означает, что можно также создать классы и программу как обычно. Но кроме того, можно проанализировать дженерики, потому что наш процессор аннотации называют прежде стирание типа.

основная суть о статическом метапрограммировании в Java, что Вы обеспечиваете метаданные (в форме аннотаций), и процессор будет в состоянии найти, что все аннотируемые классы обрабатывают их. На (более легком) примере может быть найден на Bealdung, где легкий пример формируется. По-моему, это завершено хороший источник для начала работы. Если Вы понимаете это, попытайтесь погуглить себя. Существует несколько хороших источников там, к очень для списка здесь. Также смотрите на Google AutoService , который использует процессор аннотации, для устранения стычки создания и поддержания сервисных файлов. Если Вы хотите создать классы, я рекомендую смотреть JavaPoet.

Печально, хотя, эта DOS API не позволяет нам, для управления исходным кодом. Но если Вы действительно хотите, необходимо смотреть на Проект Ломбок . Они делают это, но это не поддерживается.

<час>

, Почему это важное (Дополнительные материалы для чтения для заинтересованных среди Вас)

TL; DR: Это является довольно экранирующим мне, почему мы не используем статическое метапрограммирование так же как динамичный, потому что это имеет много много преимуществ.

Большинство разработчиков видит, что "Динамический и Статический" и непосредственный переход в заключение, настолько динамичное, лучше. Ничто неправильно, с которым, статичный имеет много отрицательных коннотаций для разработчиков. Но в этом случае (и специально для Java) это - точное наоборот.

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

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

, Чтобы завершить и выдержать сравнение как можно больше: Давайте вообразим Spring. Spring пытается найти, что весь Component аннотировал классы во времени выполнения (который мы могли упростить при помощи сервисных файлов во время компиляции), затем генерирует определенные прокси-классы (который мы уже, возможно, сделали во время компиляции) и бобовые зависимости от твердости (который, снова, мы уже, возможно, сделали во время компиляции). разговор Jake Whartons о Dagger2, в котором он объясняет, почему они переключились на статическое метапрограммирование. Я все еще не понимаю, почему крупные игроки как Spring не используют его.

Это сообщение должно закоротить, чтобы полностью объяснить те различия и почему статичный было бы более мощным. Если Вы хотите, я в настоящее время работаю над представлением для этого. Если Вы интересно и говорите на немецком языке (извините об этом), можно взглянуть на [1 110] мой веб-сайт . Там Вы находите представление, которое пытается объяснить различия через 45 минут. Только слайды все же.

3
ответ дан 27 November 2019 в 05:58
поделиться

Я не уверен, что понимаю преимущества статического метапрограммирования.

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

Я могу ошибаться в этом, я серьезно подумываю о том, чтобы задать вопрос по этому поводу, потому что не уверен, что понимаю. Кажется, что статическое метапрограммирование - это изящный прием, позволяющий обойти тот факт, что некоторые языки не хранят много информации во время компиляции, доступной во время выполнения (одна из сильных сторон Java и динамических языков).

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

0
ответ дан 7 July 2019 в 14:03
поделиться

Нет, это не возможно. Дженерики не так мощны как шаблоны. Например, аргумент шаблона может быть пользовательским типом, типом примитива или значением; но универсальный аргумент шаблона может только быть Object или подтип этого.

Редактирование: Это - старый ответ; с 2011 у нас есть Java 7, который имеет Аннотации, которые могут использоваться для такого обмана .

24
ответ дан Community 27 November 2019 в 05:58
поделиться

Смотрите на Clojure. Это - LISP с Макросами (метапрограммирование), которое работает на JVM и очень совместимо с Java.

13
ответ дан Lou Franco 27 November 2019 в 05:58
поделиться

Нет. Еще больше универсальные типы стираются к их верхней границе компилятором, таким образом, Вы не можете создать новый экземпляр универсального типа T во времени выполнения.

лучший способ сделать metaprogamming в Java должен обойти стирание типа и вручить Class<T> объект Вашего типа T. Однако, это - только взлом.

4
ответ дан Torsten Marek 27 November 2019 в 05:58
поделиться

Нет, дженерики в Java просто способ постараться не бросать Объекта.

2
ответ дан larsivi 27 November 2019 в 05:58
поделиться

В очень уменьшенном смысле, возможно? http://michid.wordpress.com/2008/08/13/type-safe-builder-pattern-in-java/

1
ответ дан jmagica 27 November 2019 в 05:58
поделиться
Другие вопросы по тегам:

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