0

考试中的问题是:编写一个名为 Registration 的类,它可以存储 T 类型的变量,其中 T 可以替换为 String、Person、Student 等。应该可以按如下方式实例化 Registration:

Registration<String> r1 = new Registration<String>();
Registration<Person> r2 = new Registration<Student>();

我无法弄清楚如何为类头的泛型部分编写声明。下面我给出了注册类。需要注意的是,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 Aug2017 考试

4

3 回答 3

1

如果Registration必须足够通用以接受任何类型,例如。String,那么您应该将其声明为:

class Registration<T> {
    private T[] roster;
    ...
    public Registration (Class<T> clazz) {
        roster = (T[])Array.newInstance(clazz, 100);
    }
    ...
} 
于 2018-04-28T04:41:03.337 回答
0

下面的代码片段会做,请注意

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>();
    }
于 2018-04-28T04:25:52.483 回答
0

问题是错误的,或者您以某种方式错误地复制了它。不存在可以满足此实例化的此类声明。

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!

发生这种情况是因为r0r1是同一个对象,因此具有相同的最后一个实例——一个 Person 实例。但是它的返回类型的泛型r0承诺是学生。这就是为什么您不能以与普通类型相同的方式分配泛型的原因。这就是为什么通配符占有一席之地的原因。这意味着泛型类型只能用于返回该类型的东西,例如。<? extends Person>,但不将它们作为参数传递。或者这意味着泛型类型只能传递该类型的东西<? super Student>,但不能返回它们。

于 2018-04-28T06:08:57.467 回答