我正在尝试使用泛型作为与Java集合类似的抽象层。下面是一个简化的示例:EmployeeRecord类存储有关employee和class的信息Table应该是通用的,并且能够存储各种类型的数据。该类型作为泛型传递给Table
。
调用存储的特定类时,我遇到了问题。
调用方法print()有什么问题? 我该如何解决?
class EmployeeRecord
{
String name;
EmployeeRecord( String name )
{
this.name = name;
}
void print()
{
System.out.println( name );
}
}
class Table<Record>
{
Record rec;
void set( Record rec )
{
this.rec = rec;
}
void printAll()
{
rec.print(); // COMPILER ERROR
/*
Test.java:27: error: cannot find symbol
rec.print();
^
symbol: method print()
location: variable rec of type Record
where Record is a type-variable:
Record extends Object declared in class Table
1 error
*/
}
}
public class Test
{
public static void main( String[] argv )
{
EmployeeRecord emp = new EmployeeRecord("John");
Table<EmployeeRecord> tab = new Table<EmployeeRecord>();
tab.set( emp );
tab.printAll();
}
}
答案 0 :(得分:1)
实现此目的的一种方法是创建所有记录类将要实现的公共接口
interface Record{
void print();
}
然后你的EmployeeRecord
课程将会是这样的
class EmployeeRecord implements Record
{
String name;
EmployeeRecord( String name )
{
this.name = name;
}
@Override
public void print()
{
System.out.println( name );
}
}
你的表格看起来像这样
class Table<T extends Record>
{
T rec;
void set( T rec )
{
this.rec = rec;
}
void printAll()
{
rec.print();
}
}
然后你从像这样的主要方法中调用它
public class Test {
public static void main(String[] args) {
EmployeeRecord emp = new EmployeeRecord("John");
Table<EmployeeRecord> tab = new Table<EmployeeRecord>();
tab.set( emp );
tab.printAll();
}
}
答案 1 :(得分:0)
Java使用类型擦除编译泛型。如果未绑定类型,编译器会将参数化类型的实例视为Object
实例。
要解决这个问题,你必须将类型绑定到某个具有所需方法的超类型:
interface Record {
...
}
class Table<T extends Record> {
...
}
绑定后,编译器知道您可以在Record
类型的实例上调用T
的任何方法。
此外,它将拒绝任何尝试使用不的子类Table
的参数化类型实例化Record
。然而,在原始代码中,您的Table
对象可以使用任何类型参数进行实例化(可能不所需的行为)。