Java 参数化方法解释
Java Parametrized method explanation
我想在 CommonInterface
中实现一个通用方法,以使用不同的参数和 return 类型实现它。
因此我有:
public interface Common {
public <T, N> T call(N n);
}
如果我很好地理解泛型逻辑(也许不是..),调用方法 return 类型 T 并作为参数接收类型 N。因此:
public class Class implements Common {
@Autowired private SomeService someService;
@Override
public <ClassDTO, Integer> ClassDTO call(Integer id) {
String s = someService.doSome(id); // suppose doSome receive an Integer as param
}
}
DoSome 方法是一个简单的方法,它接收一个整数作为输入参数:
@Service
public class SomeService {
// some @Autowired other service
public String doSome(Integer id) {
// some operation
}
}
我在 doSome(id) 调用时收到一个错误,谁说我:
The method doSome(java.lang.Integer) in the type SomeService is not applicable for the arguments (Integer)
就像如果:
public <ClassDTO, Integer> ClassDTO call(Integer id) {
}
上面的Integer
不被识别为java.lang.Integer
。我试着把 java.lang.Integer
如下:
public <ClassDTO, java.lang.Integer> ClassDTO call(Integer id) {
}
但得到其他错误..
怎么了??
如果你仔细观察 call
的覆盖:
public <ClassDTO, Integer> ClassDTO call(Integer id) {
String s = someService.doSome(id); // suppose doSome receive an Integer as param
}
您可以看到 ClassDTO
和 Integer
是 不是 实际类型,而是类型参数(如 T
和 N
), 就是这样称呼的。不遵循命名类型参数的约定可能会导致混淆。
覆盖更清楚,就像:
@Override
public <T, N> T call(N n) {
...
}
替换类型参数 ClassDTO
和 Integer
的类型将是您调用 call()
方法的类型:
Class instance = new Class();
Integer integer = 5;
ClassDTO result = instance.<ClassDTO, Integer>call(integer);
但是,这不会在调用 service.doSome(id)
时解析 compile-error。
为了使其编译,您可以使用 T
和 N
参数化 Common
接口,然后您的 Class
可以实现具有特定类型的通用接口( CommonDTO
和 Integer
):
public interface Common<T, N> {
T call(N n);
}
Class
看起来像:
public class Class implements Common<CommonDTO, Integer> {
private Service service;
@Override
public CommonDTO call(Integer n) {
return service.doSome(n);
}
}
现在可以正常编译了。
您只是忽略了 call
方法重写主体中的 Integer
与 java.lang.Integer
.
不同的事实
当跳过简单的 single-uppercase-letter 类型变量命名约定时,泛型经常发生这种情况。
参数Integer id
与doSome
取的参数不是同一类型,推测是java.lang.Integer
.
旁注:您隐藏了隐式导入的 类(Class
、Integer
),这会导致错误;而且这还不符合类型变量的命名约定。约定有时有助于防止错误!
我想在 CommonInterface
中实现一个通用方法,以使用不同的参数和 return 类型实现它。
因此我有:
public interface Common {
public <T, N> T call(N n);
}
如果我很好地理解泛型逻辑(也许不是..),调用方法 return 类型 T 并作为参数接收类型 N。因此:
public class Class implements Common {
@Autowired private SomeService someService;
@Override
public <ClassDTO, Integer> ClassDTO call(Integer id) {
String s = someService.doSome(id); // suppose doSome receive an Integer as param
}
}
DoSome 方法是一个简单的方法,它接收一个整数作为输入参数:
@Service
public class SomeService {
// some @Autowired other service
public String doSome(Integer id) {
// some operation
}
}
我在 doSome(id) 调用时收到一个错误,谁说我:
The method doSome(java.lang.Integer) in the type SomeService is not applicable for the arguments (Integer)
就像如果:
public <ClassDTO, Integer> ClassDTO call(Integer id) {
}
上面的Integer
不被识别为java.lang.Integer
。我试着把 java.lang.Integer
如下:
public <ClassDTO, java.lang.Integer> ClassDTO call(Integer id) {
}
但得到其他错误..
怎么了??
如果你仔细观察 call
的覆盖:
public <ClassDTO, Integer> ClassDTO call(Integer id) {
String s = someService.doSome(id); // suppose doSome receive an Integer as param
}
您可以看到 ClassDTO
和 Integer
是 不是 实际类型,而是类型参数(如 T
和 N
), 就是这样称呼的。不遵循命名类型参数的约定可能会导致混淆。
覆盖更清楚,就像:
@Override
public <T, N> T call(N n) {
...
}
替换类型参数 ClassDTO
和 Integer
的类型将是您调用 call()
方法的类型:
Class instance = new Class();
Integer integer = 5;
ClassDTO result = instance.<ClassDTO, Integer>call(integer);
但是,这不会在调用 service.doSome(id)
时解析 compile-error。
为了使其编译,您可以使用 T
和 N
参数化 Common
接口,然后您的 Class
可以实现具有特定类型的通用接口( CommonDTO
和 Integer
):
public interface Common<T, N> {
T call(N n);
}
Class
看起来像:
public class Class implements Common<CommonDTO, Integer> {
private Service service;
@Override
public CommonDTO call(Integer n) {
return service.doSome(n);
}
}
现在可以正常编译了。
您只是忽略了 call
方法重写主体中的 Integer
与 java.lang.Integer
.
当跳过简单的 single-uppercase-letter 类型变量命名约定时,泛型经常发生这种情况。
参数Integer id
与doSome
取的参数不是同一类型,推测是java.lang.Integer
.
旁注:您隐藏了隐式导入的 类(Class
、Integer
),这会导致错误;而且这还不符合类型变量的命名约定。约定有时有助于防止错误!