Как создать универсальный массив в Java?

Изучив различные решения на разных форумах и не найдя подходящего решения, я чувствую, что я получил нижний взломанный код, который проще всего отслеживать и кодировать:

Пример. Предположим, у вас есть несколько параметров для перейдите в предложение «IN». Просто поместите фиктивную строку в предложение «IN», скажем, «PARAM» обозначить список параметров, которые будут появляться на месте этой фиктивной строки.

    select * from TABLE_A where ATTR IN (PARAM);

Вы можете собрать все параметров в одну переменную String в вашем Java-коде. Это можно сделать следующим образом:

    String param1 = "X";
    String param2 = "Y";
    String param1 = param1.append(",").append(param2);

Вы можете добавить все ваши параметры, разделенные запятыми, в одну переменную String, 'param1', в нашем случае.

После сбора всех параметры в одну строку вы можете просто заменить фиктивный текст в вашем запросе, то есть «PARAM» в этом случае, с параметром String, т. е. param1. Вот что вам нужно сделать:

    String query = query.replaceFirst("PARAM",param1); where we have the value of query as 

    query = "select * from TABLE_A where ATTR IN (PARAM)";

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

Примечание. Хотя это не подготовленный запрос, он выполняет работу, которую я хотел, чтобы мой код выполнял.

1010
задан Cœur 19 February 2017 в 11:11
поделиться

6 ответов

Я должен задать вопрос в ответ: Ваш GenSet "проверяется" или "неконтролируем"? Что это означает?

  • Проверенный : строгий контроль типов . GenSet знает явно, какие объекты это содержит (т.е. его конструктора явно вызвали с Class<E> аргумент, и методы выдадут исключение, когда они будут передаваемыми аргументами, которые не имеют типа E. См. Collections.checkedCollection .

    -> в этом случае, необходимо записать:

    public class GenSet<E> {
    
        private E[] a;
    
        public GenSet(Class<E> c, int s) {
            // Use Array native method to create array
            // of a type only known at run time
            @SuppressWarnings("unchecked")
            final E[] a = (E[]) Array.newInstance(c, s);
            this.a = a;
        }
    
        E get(int i) {
            return a[i];
        }
    }
    
  • Неконтролируемый : слабый контроль типов . Никакая проверка типа на самом деле не сделана ни на одном из объектов, переданных как аргумент.

    -> в этом случае, необходимо записать

    public class GenSet<E> {
    
        private Object[] a;
    
        public GenSet(int s) {
            a = new Object[s];
        }
    
        E get(int i) {
            @SuppressWarnings("unchecked")
            final E e = (E) a[i];
            return e;
        }
    }
    

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

    public class GenSet<E extends Foo> { // E has an upper bound of Foo
    
        private Foo[] a; // E erases to Foo, so use Foo[]
    
        public GenSet(int s) {
            a = new Foo[s];
        }
    
        ...
    }
    

Все это следует из известного, и преднамеренный, слабость дженериков в Java: это было реализовано с помощью стирания, таким образом, "универсальные" классы не знают, с каким аргументом типа они были созданы во время выполнения и поэтому не могут обеспечить безопасность типов, если некоторый явный механизм (проверка типа) не реализован.

657
ответ дан Radiodef 19 February 2017 в 21:11
поделиться
  • 1
    Символы представлены с помощью UTF-16, что означает, что каждый символ использует по крайней мере 16 битов или 2 байта (даже символы ASCII, которые только требуют 7 битов). Если значение unicode будет достаточно больше, то единственный символ, который распечатал бы на экран, на самом деле потребует два char с. – Cemafor 20 July 2013 в 00:21

Вы могли создать Объектный массив и бросить его к E везде. Да, это не очень очевидный способ, чтобы сделать это, но это должно, по крайней мере, работать.

0
ответ дан Esko 19 February 2017 в 21:11
поделиться

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

4
ответ дан Ola Bini 19 February 2017 в 21:11
поделиться

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

общественность Stack(Class<T> clazz,int capacity) конструктор требует, чтобы Вы передали Объект класса во время выполнения, что означает, что информация о классе доступна во времени выполнения для кодирования, которому нужен он. И Class<T> форма означает, что компилятор проверит, что Объектом класса, который Вы передаете, является точно Объект класса для типа T. Не подкласс T, не суперкласс T, но точно T.

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

7
ответ дан Bill Michell 19 February 2017 в 21:11
поделиться

Это охвачено в Главе 5 (Дженерики) Эффективный Java, 2-й Выпуск , объект 25... Предпочитают списки массивам

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

@SuppressWarnings({"unchecked"})

Однако, вероятно, было бы лучше использовать Список вместо Массива.

существует интересное обсуждение этой ошибки/функции на стройплощадка OpenJDK .

10
ответ дан Jeff Olson 19 February 2017 в 21:11
поделиться

Вы можете сделать это:

E[] arr = (E[])new Object[INITIAL_ARRAY_LENGTH];

Это один из предлагаемых способов реализации общей коллекции в Эффективной Java; Пункт 26 . Нет ошибок типа, нет необходимости многократно приводить массив. Однако это вызывает предупреждение, потому что это потенциально опасно и должно использоваться с осторожностью. Как подробно описано в комментариях, этот Object [] теперь маскируется под наш тип E [] и может вызывать непредвиденные ошибки или ClassCastException , если используется небезопасно.

Как показывает опыт, такое поведение является безопасным до тех пор, пока массив приведения используется внутри (например, для поддержки структуры данных), а не возвращается и не предоставляется клиентскому коду. Если вам нужно вернуть массив универсального типа в другой код, то класс Reflection Array , который вы упомянули, будет правильным решением.


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

203
ответ дан 19 December 2019 в 20:20
поделиться
Другие вопросы по тегам:

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