为什么 Java 不允许我添加子类实例?
Why Java doesn't allow me to add subclass istances?
我在 Java 项目中遇到问题。
错误产生的代码如下:
HashMap<String, LinkedList<? extends User>> signedUpUsers =
new HashMap<>(Map.of(
"Administrator", new LinkedList<Administrator>(),
"Employee", new LinkedList<Employee>(),
"Customer", new LinkedList<Customer>()));
for (String userName : userNameList)
{
userPropertyValue = usersProperties.getProperty(userName).split(",");
String password = userPropertyValue[0].replaceAll("\s", "");
String role = userPropertyValue[1].replaceAll("\s", "");
if (role.equals("Administrator"))
{
signedUpUsers.get("Administrator").add(new Administrator(userName, password));
}
else if (role.equals("Customer"))
{
signedUpUsers.get("Customer").add(new Customer(userName, password));
}
else
{
signedUpUsers.get("Employee").add(new Employee(userName, password));
}
}
当我尝试在每个 hashmap 列表中添加新元素时出现错误,当我创建实例时,intellij 告诉我:
所需类型:捕获 ?扩展用户
提供:客户(或员工或管理员)
但是为什么,如果 Customer,Employee 和 Administrator 都是 User[ 的子类=28=]?
我应该改变什么?我的意图是拥有一个包含所有注册用户的 HashMap(我将它们保存在一个 .properties 文件中,因为我看到了,所以被更正为红色),其中键是用户的角色(管理员、员工和客户),以及值每个键都是具有该角色的每个用户的链表。
我还尝试使用 super 而不是 extends,但在那种情况下我解决了这个错误,但是在使用 Map.of()(因为 Administrator、Customer 和 Employee 不是 User 的超类)。
如果我有 3 个直接用 3 个角色对象声明的不同列表,代码就可以工作,但我想要哈希图,因为我想 return 整个注册用户除以他们的角色。
谢谢大家,希望我解释清楚了。
@Thomas 的评论中已涵盖编译器错误的原因:对于编译器,signedUpUsers.get("Administrator")
是一个 LinkedList<? extends User>
,不知道在 "Administrator"
键下,您存储了a LinkedList<Administrator>
(而不是 LinkedList<Employee>
,因此编译器不允许添加 Administrator
。
您的 signedUpUsers
变量显示了一些重要的泛型过度设计。你声明
HashMap<String, LinkedList<? extends User>> signedUpUsers =
new HashMap<>(Map.of(
"Administrator", new LinkedList<Administrator>(),
"Employee", new LinkedList<Employee>(),
"Customer", new LinkedList<Customer>()));
我建议将其更改为
HashMap<String, LinkedList<User>> signedUpUsers =
new HashMap<>(Map.of(
"Administrator", new LinkedList<User>(),
"Employee", new LinkedList<User>(),
"Customer", new LinkedList<User>()));
您可能会问“但是现在我没有类型安全,我只能在 "Administrator"
键下存储 Administrator
个实例。”但是第一个版本也不可能实现类型安全(在 运行 时,LinkedList<Administrator>
只是一个 LinkedList 并且会很乐意接受任何 Object
,并且在编译时 LinkedList<? extends User>
将不允许添加任何内容)。
如果你想要列表的类型安全,扔掉 Map
方法,并创建一个 class UserList
:
public class UserList {
private List<Administrator> administrators;
private List<Employee> employees;
private List<Customer> customers;
// add constructor, getters, adders etc. here
}
这将轻松提供所需的类型安全性。
我在 Java 项目中遇到问题。 错误产生的代码如下:
HashMap<String, LinkedList<? extends User>> signedUpUsers =
new HashMap<>(Map.of(
"Administrator", new LinkedList<Administrator>(),
"Employee", new LinkedList<Employee>(),
"Customer", new LinkedList<Customer>()));
for (String userName : userNameList)
{
userPropertyValue = usersProperties.getProperty(userName).split(",");
String password = userPropertyValue[0].replaceAll("\s", "");
String role = userPropertyValue[1].replaceAll("\s", "");
if (role.equals("Administrator"))
{
signedUpUsers.get("Administrator").add(new Administrator(userName, password));
}
else if (role.equals("Customer"))
{
signedUpUsers.get("Customer").add(new Customer(userName, password));
}
else
{
signedUpUsers.get("Employee").add(new Employee(userName, password));
}
}
当我尝试在每个 hashmap 列表中添加新元素时出现错误,当我创建实例时,intellij 告诉我:
所需类型:捕获 ?扩展用户
提供:客户(或员工或管理员)
但是为什么,如果 Customer,Employee 和 Administrator 都是 User[ 的子类=28=]?
我应该改变什么?我的意图是拥有一个包含所有注册用户的 HashMap(我将它们保存在一个 .properties 文件中,因为我看到了,所以被更正为红色),其中键是用户的角色(管理员、员工和客户),以及值每个键都是具有该角色的每个用户的链表。
我还尝试使用 super 而不是 extends,但在那种情况下我解决了这个错误,但是在使用 Map.of()(因为 Administrator、Customer 和 Employee 不是 User 的超类)。
如果我有 3 个直接用 3 个角色对象声明的不同列表,代码就可以工作,但我想要哈希图,因为我想 return 整个注册用户除以他们的角色。
谢谢大家,希望我解释清楚了。
@Thomas 的评论中已涵盖编译器错误的原因:对于编译器,signedUpUsers.get("Administrator")
是一个 LinkedList<? extends User>
,不知道在 "Administrator"
键下,您存储了a LinkedList<Administrator>
(而不是 LinkedList<Employee>
,因此编译器不允许添加 Administrator
。
您的 signedUpUsers
变量显示了一些重要的泛型过度设计。你声明
HashMap<String, LinkedList<? extends User>> signedUpUsers =
new HashMap<>(Map.of(
"Administrator", new LinkedList<Administrator>(),
"Employee", new LinkedList<Employee>(),
"Customer", new LinkedList<Customer>()));
我建议将其更改为
HashMap<String, LinkedList<User>> signedUpUsers =
new HashMap<>(Map.of(
"Administrator", new LinkedList<User>(),
"Employee", new LinkedList<User>(),
"Customer", new LinkedList<User>()));
您可能会问“但是现在我没有类型安全,我只能在 "Administrator"
键下存储 Administrator
个实例。”但是第一个版本也不可能实现类型安全(在 运行 时,LinkedList<Administrator>
只是一个 LinkedList 并且会很乐意接受任何 Object
,并且在编译时 LinkedList<? extends User>
将不允许添加任何内容)。
如果你想要列表的类型安全,扔掉 Map
方法,并创建一个 class UserList
:
public class UserList {
private List<Administrator> administrators;
private List<Employee> employees;
private List<Customer> customers;
// add constructor, getters, adders etc. here
}
这将轻松提供所需的类型安全性。