use*_*676 3 java generics immutability
我的界面看起来像:
package com.sample.service;
import com.sample.model.Request;
public interface Service<T> {
void add(T domain);
<E> boolean update(Request<E> request);
}
Run Code Online (Sandbox Code Playgroud)
Request.java在哪里
package com.sample.model;
public class Request<E> {
private final E entity;
public Request(E entity) {
this.entity = entity;
}
public E getEntity() {
return entity;
}
}
Run Code Online (Sandbox Code Playgroud)
以下是我的实施
package com.sample.service;
import com.sample.domain.User;
import com.sample.model.Form;
import com.sample.model.Request;
public class UserServiceImpl implements Service<User> {
@Override
public void add(User user) {
System.out.println("add: " + user);
}
@Override
public <Form> boolean update(Request<Form> request) {
System.out.println("update: " + request);
Form form = request.getEntity();
//form.setUsername("some_username");//This line caused compile error
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
这是Form.java
package com.sample.model;
public class Form {
private String username;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
@Override
public String toString() {
return username;
}
}
Run Code Online (Sandbox Code Playgroud)
和User.java
package com.sample.domain;
public class User {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
}
Run Code Online (Sandbox Code Playgroud)
当我编译并执行这些代码时,一切都很好.但是,当我取消注释UserServiceImpl中注释的行时,我得到了编译错误
UserServiceImpl.java:19: error: cannot find symbol
form.setUsername("some_username");
Run Code Online (Sandbox Code Playgroud)
我的问题是为什么无法找到表单对象中的setUsername方法?表单对象是可变的.
小智 6
在你的代码中
public <Form> boolean update(Request<Form> request)
Run Code Online (Sandbox Code Playgroud)
Form不是com.sample.model.Form.相反,它是另一个通用参数,就像E在
<E> boolean update(Request<E> request);
Run Code Online (Sandbox Code Playgroud)
.E即使您碰巧给它的名称与真实类的名称一致,编译器也一无所知.编译器唯一可以确定的E(或Form在同一个上下文中)是它是一个Object实例.而且Object没有任何getEntity方法.
如果您来自C++背景,那么您正在尝试对模板进行明确的专业化.但是,Java泛型不是模板.他们不生成代码.它们只提供一些编译时检查和运行时类型转换(有一些,但不多).在Java Generics的上下文中查找" 类型擦除 ".
要实现更有用的解决方案,您可以尝试确定参数的接口类型update().如果存在必需的接口,请将其写为Java interface并用作参数类型.如果没有(极少数情况下),您仍然可以使用空interface来进行标记,但是您需要自己翻转参数 - 假设UserServiceImpl知道传递给哪种类型update().
在以太网情况下,update()中可能不需要泛型.
| 归档时间: |
|
| 查看次数: |
495 次 |
| 最近记录: |