Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

двумерный массив универсального типа

307
29 июля 2010 года
Artem_3A
863 / / 11.04.2008
День добрый, уважаемые!
Вот решил тут прокачаться в Java, обзавелся парой умных книжек, но столкнулся с проблемой.

 
Код:
public class Map<Cell extends AbstractCell> {
    protected Cell[][] field;
    ...
    public Map(int field_size) {
        field = new Cell[field_size][field_size];
    }
}


Но вот тут получаю "error: generic array creation".
Порывшись в интернетах нашел вот такой костыль.

 
Код:
field = (Cell[][])new Object[field_size][field_size];


Есть ли метод более очевидный и естественный?

ЗЫ: (для самопроверки) при создании такого массива, как я понимаю, конструкторы не вызываются и создается лишь массив ссылок, но не самих объектов, верно?
307
29 июля 2010 года
Artem_3A
863 / / 11.04.2008
Вдогонку еще вот такой трабл возник.

 
Код:
public Map(int field_size) {
        field = (Cell[][])new Object[field_size][field_size];
        for(Cell[] row : field)
            for(Cell cur : row)
                cur = new Cell();
    }


Получаю "error: unexpected type. required: class. found: type parameter Cell".

Это дело основательно ввело меня в ступор... Уважаемые эксперты, подскажите где я начудачил или как это побороть!?
1.8K
29 июля 2010 года
LM(AL/M)
332 / / 20.12.2005
1)
Цитата: Artem_3A

 
Код:
public class Map<Cell extends AbstractCell> {
    protected Cell[][] field;
    ...


почему бы не написать просто

 
Код:
public class Map {
    protected AbstractCell[][] field;
    ...

?
1.8K
29 июля 2010 года
LM(AL/M)
332 / / 20.12.2005
2)
Цитата: Artem_3A

 
Код:
public CMap(int field_size) {
        field = (Cell[][])new Object[field_size][field_size];
        for(Cell[] row : field)
            for(Cell cur : row)
                cur = new Cell();
    }

Получаю "error: unexpected type. required: class. found: type parameter Cell".



error на строчке cur = new Cell(); ? ; )

307
30 июля 2010 года
Artem_3A
863 / / 11.04.2008
1. потому что я как бы осваиваю, а по этому не ищу легких путей!=)
2. да, верно, именно на этой строчке.
307
30 июля 2010 года
Artem_3A
863 / / 11.04.2008
в общем почитал я интеренеты и понял, что мои желания не совпадают с возможностями Java, а жаль...
502
13 августа 2010 года
Jail
550 / / 30.01.2007
книжка Effective Java тебе в помощь. после нее, не будешь больше задавать подобных вопросов
276
13 августа 2010 года
Rebbit
1.1K / / 01.08.2005
Цитата: Artem_3A
в общем почитал я интеренеты и понял, что мои желания не совпадают с возможностями Java, а жаль...


Мой друг, вы ошибаетесь. Ее просто надо уметь готовить :)

Во-первых:

Цитата: Artem_3A
ЗЫ: (для самопроверки) при создании такого массива, как я понимаю, конструкторы не вызываются и создается лишь массив ссылок, но не самих объектов, верно?


Конструкторы обьектов не вызываются. Масив будет заполнен нулами. Но вызывается коструктор массива. А поскольку джава язик довольно безопасный то масиву уже при его создании просто необходимо знать класс своих елементов. И тут надо сделать важное замечание - Cell не есть классом. Ето только место для подстановки класса. Это накладывает свое играничения с которыми вы столкнулись.

Во-вторых:
поскольку ваш пример (как на меня) лишен всяческой смысловой нагрузки, то осмелюсь паредположить что он суто тренировочный. Тогда позвольте заметить что вы начали експерименты в довольно сложной области дженериков. Там много ограничений, большинство которых розруливается, но для етого надо хорошо ориентироваться в роботе компилятора и виртуальной машины. Тоесть дженерики - ето не то с чего следует начинать знакомство для начинающего. Хотя вы уже не первый год замужем и так как вам учить операторы смысла нет - то я понимаю почему вы играетесь с дженериками. Советую вам почитать главу про дженерики в книге Хорстмена и Корнела по 5 или 6 джаве. Там эти ограничения красиво описаны (вообще хорошая книга которая обясняет именноо детали. В том числе и особенности каста масива с которым вы тоже столкнулись. Советую внимательно читать заментки с знаком восклицания. Все самое интересное именно там).

В-третьих:
ошибка на new Cell(); - еще не приговор.
следующий пример не совсем то что вам нужно так как в нем класс GenTest уже не есть дженериком, а только наследуется от дженерика, но всеже думаю пример будет вам интересным. Такой подход используют, к примеру, при создание ДАО для роботы с сущностями бд. Базовый абстрактный клас ДАО умеет делать инсерт, апдейт, делит, поиск по ид. А для каждой конкретной сущности делается недженерик потомок от абстрактного дженерика со своими дополнительными методами-селекторами.

Код:
package test;

import java.lang.reflect.ParameterizedType;

class AbstractGenTest<T> {
   
    protected Class<T> persistentClass;
   
    public AbstractGenTest() {
        persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
    }
   
    public T createNewInstance() throws InstantiationException, IllegalAccessException {
        return persistentClass.newInstance();
    }
   
}

public class GenTest extends AbstractGenTest<TestClass>{
    public static void main(String[] args) throws InstantiationException, IllegalAccessException {
        GenTest genTest = new GenTest();
        genTest.createNewInstance();
    }
}

class TestClass {

    public TestClass() {
        super();
        System.out.println("TestClass created");
    }
}
502
13 августа 2010 года
Jail
550 / / 30.01.2007
Цитата: Rebbit
Советую вам почитать главу про дженерики в книге Хорстмена и Корнела по 5 или 6 джаве. Там эти ограничения красиво описаны (вообще хорошая книга которая обясняет именноо детали. В том числе и особенности каста масива с которым вы тоже столкнулись. Советую внимательно читать заментки с знаком восклицания. Все самое интересное именно там)


а стоило ли столько писать, учитывая, что все это расписано в книге???
во вторых: даже классика Core Java Хорстмана, конечно внесет ясность в восприятие картины, но не научит, как именно и главное в какой ситуации правильно пользоваться тем или иным паттерном. это касается не только generics, но и всего остального. лучше всего это объясняется именно в Effective Java, о чем я и упомянал выше. Здается мне, что вы ее не читали. Да кстати, массивы с generic кодом никогда не миксуют, это грубая ошибка.
какой бы язык вы не учили, в class-room'ах (предположим даже Английский) даются лишь базовы знания, общие правила и т.д. Но как правильно пользоваться языком и как объясниться на этом языке вас не научат ни в одном class-room'e, а это самый важный аспект любого языка.

276
13 августа 2010 года
Rebbit
1.1K / / 01.08.2005
Цитата: Jail
а стоило ли столько писать, учитывая, что все это расписано в книге???


А я люлю пописать на досуге :)

Цитата: Jail
это объясняется именно в Effective Java, о чем я и упомянал выше. Здается мне, что вы ее не читали.


Не читал. Но раз вы так советуете, то прочитаю. А как вы так точно определили что не читал?

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

502
13 августа 2010 года
Jail
550 / / 30.01.2007
[QUOTE=Rebbit]Не читал. Но раз вы так советуете, то прочитаю. А как вы так точно определили что не читал? [/QUOTE]
а я телепат :D
шутко конеш... ваши довыды вполне обстоятельны и правдоподобны, но.... :)
а Effective Java - это книжка ну просто Must to Read, для любого профессионального Java developer'a.
читал я Core Java оба тома: после, появилось просветление, что такое вообще Java и с чем ее едят (перед этим читал книгу Java Tutorials - полный сумбур - это антипаттерн! даже не тратьте время!). Все довольно обстоятельно, последовательно и ясно изложено в Core Java.
После прочтения Effective Java: пришло озарение, как же правильно программировать на Java и как это легко. Мда и после, просматривал sample apps из Core Java и обнаружил, что Horstmann в некоторых местах грубо нарушает основополагающие паттерны, на кот. строиться сам язык Java. в Effective Java приводяться постонно примеры из стандартной библиотеки Java и пояснятеся почему было принято именно такое решение, а не иное другое - ошибочне (примеры ошибочного кода так же приводяться).
На последок, автор Joshua Bloch - на текущий момент главный Java архитектов в компании Google, ранее работавший в Sun и приложил не мало усилий в создание стандартной библиотеки java вплоть до версии 1.5. Обещаю, после прочтения вы все сами поймете :)
276
13 августа 2010 года
Rebbit
1.1K / / 01.08.2005
Цитата: Jail
Horstmann в некоторых местах грубо нарушает основополагающие паттерны, на кот. строиться сам язык Java


Спорить не стану, так как листингов, впрочем как и описаний АПИ, не читал воовсе. Меня в то время интересовали именно детали синтаксиса и всякого рода мелочи, так как я сежжал с РНР на Джаву.
И должон сказать что многое из прочитаного мне пригодилось.
Например описание того что произойдет если есть try/cache/finally много ретурнов внутри, специфыка нестед класов и анонимных классов, особенности сериализации и десериализации сложных структур данных и т.п. . Возможно в Effective Java эти вопросы тоже россматриваются и даже с более правильной стороны. Собственно я чувствую что у меня есть некая бреш в знаниях именно в использовании языка на таком уровне.
Ну и раз уже о книгах говорим то каково ваше мнение о роботах мартина Фаулера "Рефакторинг" и "Архитектура корпоративных программных приложений" (если читали).
Мое мнение о етих книгах в общих чертах положительное, но кажется что уж очень много кода там в примерах. Тоже много пропускал. А про вторую книгу - ее полезно читать после знакомства с несколькими существующими технологиями в которых используются схожые подходи (иначе можно и недопонять).
[COLOR=Silver]
[/COLOR]

502
13 августа 2010 года
Jail
550 / / 30.01.2007
Цитата: Rebbit

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


хоть рефлексия это и медленный способ и его нужно стараться всячески избегать (об этом Хорстманн тоже пишет, но сам часто использует рефлексию в своих samples apps....), но думаю можно лишь изредка...
Generics обеспечивает безопастность типов и необходимо строить классы каждый раз исходя из соображений безопасности, что бы злостный юзер ваших классов не смог скомпрометировать ваш класс с помошью рефлекции! потому как имеется куча способов сделать это.
ну маленький пример где вступает в дело рефлекция, при этом type safe обеспечена:

Код:
import java.lang.annotation.*;
import java.lang.reflect.*;
 
public class PrintAnnotation {
    // Use of asSubclass to safely cast to a bounded type token
    static Annotation getAnnotation(AnnotatedElement element,
                                    String annotationTypeName) {
        Class<?> annotationType = null; // Unbounded type token
        try {
            annotationType = Class.forName(annotationTypeName);
        } catch (Exception ex) {
            throw new IllegalArgumentException(ex);
        }
        return element.getAnnotation(
            annotationType.asSubclass(Annotation.class));
    }
 
    // Test program to print named annotation of named class
    public static void main(String[] args) throws Exception {
        if (args.length != 2) {
            System.out.println(
                "Usage: java PrintAnnotation <class> <annotation>");
            System.exit(1);
        }
        String className = args[0];
        String annotationTypeName = args[1];  
        Class<?> klass = Class.forName(className);
        System.out.println(getAnnotation(klass, annotationTypeName));
    }
}
можно даже иногда миксить массивы с generic types, но это грубейшая ошибка и только в редких исключениях это возможно:
Код:
import java.util.*;
 
public class Stack<E> {
    private E[] elements;
    private int size = 0;
    private static final int DEFAULT_INITIAL_CAPACITY = 16;
 
    // The elements array will contain only E instances from push(E).
    // This is sufficient to ensure type safety, but the runtime
    // type of the array won't be E[]; it will always be Object[]!
    @SuppressWarnings("unchecked")  
        public Stack() {
        elements = (E[]) new Object[DEFAULT_INITIAL_CAPACITY];
    }
 
    public void push(E e) {
        ensureCapacity();
        elements[size++] = e;
    }
 
    public E pop() {
        if (size==0)
            throw new EmptyStackException();
        E result = elements[--size];
        elements[size] = null; // Eliminate obsolete reference
        return result;
    }
 
    public boolean isEmpty() {
        return size == 0;
    }
 
    private void ensureCapacity() {
        if (elements.length == size)
            elements = Arrays.copyOf(elements, 2 * size + 1);
    }
 
    // pushAll method without wildcard type - deficient!
//  public void pushAll(Iterable<E> src) {
//      for (E e : src)
//          push(e);
//  }
 
     // Wildcard type for parameter that serves as an E producer
    public void pushAll(Iterable<? extends E> src) {
        for (E e : src)
            push(e);
    }
 
    // popAll method without wildcard type - deficient!
//  public void popAll(Collection<E> dst) {
//      while (!isEmpty())
//          dst.add(pop());
//  }
 
    // Wildcard type for parameter that serves as an E consumer
    public void popAll(Collection<? super E> dst) {
        while (!isEmpty())
            dst.add(pop());
    }
 
    // Little program to exercise our generic Stack
    public static void main(String[] args) {
        Stack<Number> numberStack = new Stack<Number>();
        Iterable<Integer> integers = Arrays.asList(3, 1, 4, 1, 5, 9);
        numberStack.pushAll(integers);
 
        Collection<Object> objects = new ArrayList<Object>();
        numberStack.popAll(objects);
 
        System.out.println(objects);
    }
}
есть и куча других паттернов типа Generic singleton factory method. ну, короче, в книге это все описано намного лучше ;)
502
13 августа 2010 года
Jail
550 / / 30.01.2007
Цитата: Rebbit
Возможно в Effective Java эти вопросы тоже россматриваются и даже с более правильной стороны.[COLOR=Silver]
[/COLOR]


вот именно. в этом и вся соль.

Цитата: Rebbit
Ну и раз уже о книгах говорим то каково ваше мнение о роботах мартина Фаулера "Рефакторинг" и "Архитектура корпоративных программных приложений" (если читали).


Книжка Мартина Фаулера это хорошее пособие в глубь тематики разбора кода. Вообщем, согласен - очень хорошие впечатления остались. Но теперь за меня всю подобную работу делает Intellij IDEA :)
Про вторую ничего сказать не могу.. я не Enterprise developer и это направление меня не сильно интересует. мое направление - Java Desktop Apps, Desktop integration solutions и Java2D. вообщем десктоп.
недавно принял решение переквалифицироваться в Android Engineer. 2 книги уже приобрел, теперь нужно время прочесть и некоторую практику накопить.

63K
07 сентября 2010 года
v_danek
2 / / 07.09.2010
Цитата: LM(AL/M)
1)

почему бы не написать просто
 
Код:
public class Map {
    protected AbstractCell[][] field;
    ...

?





потому что в умных книжках пишут, что raw-типы - это плохо))

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог