[英]Using Generics: Instantiating an object of a generic class with parent and child values in generic
考試中的問題指出:編寫一個名為Registration的類,該類可以存儲類型T的變量,其中T可以用String,Person,Student等替換。應該可以如下實例化Registration:
Registration<String> r1 = new Registration<String>();
Registration<Person> r2 = new Registration<Student>();
我無法弄清楚如何為類頭的泛型部分編寫聲明。 下面我給了Registration類。 注意,類Student繼承了Person類。
import java.util.List;
import java.util.ArrayList;
public class Registration<T extends Person> //I believe my issue is here{
private T [] roster;
private List<T> waitList;
private static int rosterCount;
private T lastInstance;
public Registration () {
roster = (T[]) new Object[100];
waitList = new ArrayList<>();
rosterCount = 0;
lastInstance = null;
}
public void addIndex (T t) {
if (rosterCount>=100) {
waitList.add(t);
}
else {
roster [rosterCount] = t;
rosterCount++;
}
lastInstance = t;
}
public T getLastInstance() {
return lastInstance;
}
public int getRosterCount() {
return rosterCount;
}
public int getWaitListCount() {
return waitList.size();
}
}
**摘自Uoft CSC207 2017年8月考試
如果Registration
必須足夠通用以接受任何類型,例如 String
,那么您應該將其聲明為:
class Registration<T> {
private T[] roster;
...
public Registration (Class<T> clazz) {
roster = (T[])Array.newInstance(clazz, 100);
}
...
}
以下代碼片段可以做到,請注意
Registration<Person> r2 = new Registration<Student>();
無法執行,因此請在底部重寫。
static class Person {}
static class Student extends Person {}
static class Registration<T> {
private T[] roster;
private List<T> waitList;
static int rosterCount;
private T lastInstance;
public Registration() {
roster = (T[]) new Object[100]; ;
waitList = new ArrayList<T>();
}
}
public static void main(String[] args) {
Registration<String> r1 = new Registration<String>();
Registration<? extends Person> r2 = new Registration<Student>();
}
這個問題是錯誤的,或者您以某種方式錯誤地復制了它。 沒有可以滿足此實例化的此類聲明。
Registration<Person> r = new Registration<Student>();
這是因為通過將對象放在r
您可以違反其約束。
例如:
Registration<Student> r0 = new Registration<Student>();
r0.addIndex(new Student());
Student s0 = r0.getLastInstance(); // returns a student instance
r0. addIndex(new Person()); // error, person is not a subclass of student
Registration<Person> r1 = r0; // error, but we will pretend it's allowed - you could force it with a cast
r1.addIndex(new Person()); // this is cool, but what happens to the underlying object?
Person p = r1.getLastInstance(); // this is fine, just like before
Student s1 = r0.getLastInstance(); // error, returns a person instance!
發生這種情況是因為r0
和r1
是相同的對象,因此具有相同的最后一個實例-Person實例。 但是r0
的通用類型保證它的返回類型是Student。 這就是為什么您不能以與普通類型相同的方式分配泛型的原因。 這就是為什么通配符有其位置的原因。 這意味着通用類型只能用於返回該類型的東西,例如。 <? extends Person>
<? extends Person>
,但不將其作為參數傳遞。 還是意味着通用類型只能傳遞該類型的東西<? super Student>
<? super Student>
,但不將其返回。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.