Добавляет ли & lt; & gt; при распределении универсального изменения класса семантика java-программы [duplicate]

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

Итак, если вы используете Angular, React или любые другие фреймворки, которые делают два способа связывания данных, эта проблема просто исправлена ​​для вас, поэтому простым языком ваш результат undefined на первом этапе, поэтому вы получили result = undefined до получения данных, а затем, как только вы получите результат , он будет обновляться и присваиваться новому значению, которое отвечает на ваш вызов Ajax ...

Но как вы можете сделать это в чистом javascript или jQuery, например, как вы задали этот вопрос?

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

Например, в вашем случае, в котором вы используете jQuery, вы можете сделать что-то вроде этого:

$(document).ready(function(){
    function foo() {
        $.ajax({url: "api/data", success: function(data){
            fooDone(data); //after we have data, we pass it to fooDone
        }});
    };

    function fooDone(data) {
        console.log(data); //fooDone has the data and console.log it
    };

    foo(); //call happens here
});

Для получения дополнительной информации n изучение обещаний и наблюдаемых, которые являются новыми способами для создания асинхронных материалов.

407
задан ROMANIA_engineer 8 May 2015 в 15:27
поделиться

7 ответов

Проблема с

List<String> list = new LinkedList();

заключается в том, что с левой стороны вы используете общий тип List<String>, где с правой стороны вы используете raw тип LinkedList. Необработанные типы в Java эффективно существуют только для совместимости с кодом pre-generics и никогда не должны использоваться в новом коде, если вам не обязательно.

Теперь, если у Java были генерики с самого начала и не имели типов , такие как LinkedList, которые изначально были созданы до того, как появились дженерики, вероятно, это могло бы сделать так, чтобы конструктор для генерического типа автоматически обнаруживал параметры своего типа с левой стороны задания, если это было возможно. Но это не так, и он должен относиться к сырым типам и общим типам по-разному для обратной совместимости. Это оставляет им необходимость сделать немного отличающимся , но не менее удобным, способом объявления нового экземпляра родового объекта без необходимости повторять его параметры типа ... алмазный оператор.

Что касается вашего исходного примера List<String> list = new LinkedList(), компилятор генерирует предупреждение для этого назначения, потому что он должен. Рассмотрим это:

List<String> strings = ... // some list that contains some strings

// Totally legal since you used the raw type and lost all type checking!
List<Integer> integers = new LinkedList(strings);

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

// Not legal since the right side is actually generic!
List<Integer> integers = new LinkedList<>(strings);

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

Я думаю, что ключевым моментом для понимания является то, что необработанные типы (без <>) нельзя рассматривать так же, как общие типы. Когда вы объявляете необработанный тип, вы не получаете никаких преимуществ и типов проверки дженериков. Вы также должны иметь в виду, что дженерики являются частью общего назначения языка Java ... они не просто применяются к конструкторам no-arg из Collection s!

452
ответ дан ColinD 24 August 2018 в 18:10
поделиться

Все сказанные в других ответах действительны, но варианты использования не полностью действительны IMHO. Если вы проверите Guava и особенно связанные с коллекциями вещи, то это было сделано со статическими методами. Например. Lists.newArrayList () , который позволяет вам писать

List<String> names = Lists.newArrayList();

или со статическим импортом

import static com.google.common.collect.Lists.*;
...
List<String> names = newArrayList();
List<String> names = newArrayList("one", "two", "three");

В Guava есть и другие очень мощные функции, подобные этому, и Я действительно не могу придумать многого использования для & lt;>.

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

4
ответ дан allprog 24 August 2018 в 18:10
поделиться

Когда вы пишете List<String> list = new LinkedList();, компилятор выдает предупреждение «unchecked». Вы можете игнорировать его, но если вы игнорировали эти предупреждения, вы также можете пропустить предупреждение, которое уведомляет вас о проблеме безопасности реального типа.

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

6
ответ дан axtavt 24 August 2018 в 18:10
поделиться

Точка для оператора алмаза - это просто сокращение ввода кода при объявлении общих типов.

Единственное отличие, если вы указываете в Java 5 и 6,

List<String> list = new ArrayList();

, вы должны указать @SuppressWarnings("unchecked") на list (в противном случае вы получите предупреждение без предупреждения). Я понимаю, что алмазный оператор пытается упростить разработку. Это не имеет никакого отношения к выполнению дженериков во время выполнения.

3
ответ дан Buhake Sindi 24 August 2018 в 18:10
поделиться

Теоретически оператор алмаза позволяет писать более компактный (и читаемый) код, сохраняя повторяющиеся аргументы типа. На практике это всего лишь два путаных символа, которые больше не дают вам ничего. Почему?

  1. Ни один здравомыслящий программист не использует необработанные типы в новом коде. Таким образом, компилятор мог просто предположить, что, не создавая аргументов типа, вы хотите, чтобы он их выводил.
  2. Оператор алмаза не предоставляет информацию о типе, он просто говорит компилятор, «все будет хорошо». Поэтому, опуская его, вы не можете навредить.

IMHO, имеющий четкий и простой способ отметить источник как Java 7, будет более полезен, чем изобретая такие странные вещи. В таком помеченном виде необработанные типы кода могут быть запрещены, не теряя ничего.

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

package 7 com.example;

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

14
ответ дан maaartinus 24 August 2018 в 18:10
поделиться

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

Теперь, чтобы объяснить весь пух об определении типов. Вы правы, что тип удаляется во время выполнения, но как только вы хотите извлечь что-то из списка с определением типа, вы возвращаете его как тип, который вы определили при объявлении списка, иначе он потеряет все определенные функции и будет иметь только Объектные функции, за исключением случаев, когда вы отбрасываете извлеченный объект к его исходному типу, который иногда может быть очень сложным и приводит к исключению ClassCastException.

Использование List<String> list = new LinkedList() будет получать предупреждения rawtype.

33
ответ дан Octavian Damiean 24 August 2018 в 18:10
поделиться

Эта строка вызывает предупреждение [unchecked]:

List<String> list = new LinkedList();

Итак, вопрос трансформируется: почему предупреждение [unchecked] не подавляется автоматически только для случая создания новой коллекции?

Думаю, это было бы намного сложнее, чем добавить функцию <>.

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

15
ответ дан Roman 24 August 2018 в 18:10
поделиться
Другие вопросы по тегам:

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