2014-10-13 3 views
0

Предположим, что у меня есть класс с именем NodeList с двумя полями, называемый value (тип Object) и index (тип int). NodeList реализует интерфейс под названием Copiable с помощью одного метода, который называется copyNotSyncronized().Инициализация дженериков в Java

Я хочу, чтобы версия copyNotSincronyzed()NodeList признать, если this.value реализует Copiable и, если это произойдет:

  1. Использование copyNotSincronyzed() на this.value и ...
  2. ... построить новый NodeList объект, который есть this.value.copyNotSincronyzed() как поле value.

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

Какие ошибки я сделал?

public class NodeList implements Copiable { 

    int index; 
    Object value; 

public NodeList(Object value, int index){ 
[...] 
} 

NodeList copyNotSincronyzed(){ 
    NodeList copied; 
    if( onArray.findPositionsOfElement(this.value.getClass().getInterfaces() , this.getClass().getInterfaces()[0])[0] !=-1 ) 
    // aka if this.value implements the same interface of this class (aka Copiable) 
    { 
// Following line features three errors: 
    // Incorrect number of arguments for type Class<T>; it cannot be parameterized with arguments <T, Copiable> 
    // T cannot be resolved to a type 
    // Syntax error on token "implements", , expected 
    Class<T implements Copiable> copiedObject = this.value; 


    copiedObject=copiedObject.copyNotSincronyzed(); 
    copied = new NodeList(copiedObject , this.index); 
    } 
    else copied = new NodeList(this.value, this.index); 

    } 

} 
+0

«Копируемая» - это опечатка. Вы имели в виду называть его «Copyable»? (править) 'Sincronyzed' тоже. lolz –

+1

Err ... да. Извините, английский не мой первый язык. – Argonath

ответ

2

это.значение имеет тип Object. И вы пытаетесь ввести его в тип Class<T implements Copiable>. Компилятор не знает, как это сделать, поэтому вы получаете ошибку компиляции.

Для того, чтобы сделать эту проверку, вы должны использовать оператор InstanceOf, в сочетании с броском, как это:

if (this.value instanceof Copiable){ // check that the instance implements an interface 
    Copiable asCopiable = (Copiable)this.value; // safely cast to the appropriate type 
} 

Обратите внимание, что ваша проблема не имеет ничего общего с обобщениями.

0

Интерфейс - это тип, как класс. Поэтому, когда другой класс реализует его, любой объект этого класса может использоваться полиморфно как этот интерфейс.

Это означает, что вы можете проверить, реализует ли этот объект этот интерфейс, просто используя x instanceof Y. Это оператор, который сообщает вам, является ли x «Y», а Y может быть либо классом, либо интерфейсом.

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

Для самого кода я отсылаю вас к ответу Виталия.

0

Java имеет интерфейс Clonable, который позволяет клонировать несвязанные (несинхронизированные) объекты с помощью метода Object clone(). Существует много споров вокруг этого, и нижняя линия заключается в том, что он обескуражен.

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

Потому что Clonable является наследником, у него нет дженериков.Давайте сделаем Copyable в качестве замены для Clonable (и переименовать clone() в copyNotSyncronyzed())

public interface Copyable<T> { 
    T copyNotSyncronyzed(); 
} 

public class NodeList implements Copyable<NodeList> { 
    private int  index; // make final too unless you plan to change it at some point 
    private Object value; // make final too unless you plan to change it at some point 

    public NodeList(final Object value, final int index) { 
     this.value = value; 
     this.index = index; 
    } 

    @Override 
    public NodeList copyNotSyncronyzed() { 
     if (value instanceof Copyable) { 
      Object copiedObject = ((Copyable<?>)this.value).copyNotSyncronyzed(); 

      return new NodeList(copiedObject, this.index); 
     } else 
      return new NodeList(this.value, this.index); 
    } 
} 

Последний вопрос, если вы действительно счастливы с этой структурой, поскольку она копирует связанные value экземпляры, если они не являются Copyable. Это может создать опасные ситуации, так как код, вызывающий copyNotSyncronyzed(), может ожидать, что он будет полностью не связан с оригиналом.

Например, если значение равно int[]. Вы создаете копию с использованием copyNotSyncronyzed(), затем вы меняете некоторые значения в массиве, а lo и behold также изменяются значения в массиве исходного объекта.

Смежные вопросы