2016-07-11 4 views
0

Я пытаюсь расширить LinkedHashMap из класса моих учеников. Под этим я хочу привести все функциональные возможности Карты, например Map.put(value), Map.get(key). Я просто создаю объект внутри PSVM и не делаю статических ссылок, но все же получаю следующую ошибку. Может кто-нибудь указать мне, какую ошибку я здесь делаю? Также есть ли лучший подход к достижению этой задачи? Заранее спасибо!Ошибка при расширении LinkedHashMap

import java.util.LinkedHashMap; 

public class Students<Integer,String> extends LinkedHashMap<Integer,String> { 

    public static void main(String args[]) {      // line 5 
     Students<Integer,String> students = new Students<>(); // line 6 
     students.put(1, "s1"); 
     students.put(2, "s2"); 
     students.put(3, "s3"); 

     System.out.println(students.get(1)); 
    } 

} 

Сообщение об ошибке:

>> javac Students.java 
Students.java:5: error: non-static type variable String cannot be referenced from a static context 
     public static void main(String args[]) { 
           ^
Students.java:6: error: non-static type variable Integer cannot be referenced from a static context 
       Students<Integer,String> students = new Students<>(); 
         ^
Students.java:6: error: non-static type variable String cannot be referenced from a static context 
       Students<Integer,String> students = new Students<>(); 
           ^
Students.java:6: error: unexpected type 
       Students<Integer,String> students = new Students<>(); 
                   ^
    required: class 
    found: <Integer,String>Students<Integer,String> 
    where Integer,String are type-variables: 
    Integer extends Object declared in class Students 
    String extends Object declared in class Students 
4 errors 
+1

Вы назвали свой общий тип, используя имена стандартных классов Java. Ваш код похож на 'class Students extends LinkedHashMap {' ​​'Учащиеся students =', но внутри него 'String' и' Integer' не будут обрабатываться как 'java.lang.String' или' java.lang.Integer' по умолчанию больше. – Pshemo

+0

Не расширяйте, попробуйте использовать композицию. –

+0

Спасибо Gaurava и @Pshemo –

ответ

4

Поступая

class Student<Integer, String> 

Вы определили свои собственные обобщенные типы Integer и String. Они связаны с экземпляром класса Student, однако вы также пытаетесь использовать эти новые общие типы в своем методе main(), который является статическим, а не классом экземпляра, и это недопустимо. То, что вы намеревались использовать в качестве java.lang.String

Простое решение является

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

например.

public class Students { 
    private final Map<Integer, String> map = new LinkedHashMap(); 

    public void put(int num, String str) { map.put(num, str); } 

    public String get(int num) { return map.get(num); } 

    public static void main(String args[]) { 
     Students students = new Students(); 
     students.put(1, "s1"); 
     students.put(2, "s2"); 
     students.put(3, "s3"); 

     System.out.println(students.get(1)); 
    } 
} 
+0

Ну. Хотя другие ответы в равной степени обеспечивали решение, вот то, что я точно искал. Большое спасибо.. ! –

+1

Могу ли я узнать, почему расширение LinkedHashMap устарело. Он менее эффективен? –

+2

@SwadhikarC это не об эффективности его о количестве методов, которые вы раскрываете, и этот класс должен был бы поддерживать в будущем. LinkedHashMap имеет около 60 методов, и есть очень хороший шанс, что вы закончите использовать один из этих методов таким образом, чтобы LHM или вы не намеревались. –

1

Удалить переменные типа на объявлении класса:

public class Students<Integer,String> extends LinkedHashMap<Integer,String> 

должен быть

public class Students extends LinkedHashMap<Integer,String> 

Вы фактически объявляя переменные типа, чьи имена pen, чтобы быть тем же самым, что и классы Java, что означает, что ваши переменные типа имеют приоритет над именами классов и скрывают их; ваше определение класса в настоящее время семантический идентично:

public class Students<I, S> extends LinkedHashMap<I, S> 
+0

Ну, это аккуратное объяснение .. Спасибо, что поделились ..! –

1

В

public class Students<Integer,String> extends LinkedHashMap<Integer,String> 

вы объявляете параметры универсального типа, называемые Integer и String, которые скрывают имена стандартных классов Java. не

Если вы хотите, чтобы ваш Students класс поддерживать только java.lang.Integer ключи и java.lang.String значения, используйте:

public class Students extends LinkedHashMap<Integer,String> 

, но тогда вы бы объявить и создать экземпляр класса с:

Students students = new Students(); 

, так как это будет не дольше имеют параметры типового типа.

Если вы хотите, чтобы ваш Students класс порождающим, использовать более стандартные имена для параметров типа (которые не скрывают стандартные классы Java):

public class Students<K,V> extends LinkedHashMap<K,V> 
1

С объявлением

class Students<Integer,String> ... 

вы не ссылаетесь на существующие классы java.lang.Integer и java.lang.String, но вы объявляете свой собственный type parameters для общего класса Students.

Как ваш класс уже должен быть LinkedHashMap<Integer,String> просто удалить эти параметры типа:

class Students extends LinkedHashMap<Integer,String> ... 

В качестве примечания: Это хорошая привычка называть собственные параметры типа для универсальных типов с одиночными прописными буквами, которые также предотвращает такие путаницы. Пример: class Students<I, S> ....

1
public class Students<T,E> extends LinkedHashMap<T,E> {