sys*_*738 55 java generics types
我想使用泛型类型来确保方法的参数具有相同的类型,如下所示:
public static <T> void x(T a, T b)
Run Code Online (Sandbox Code Playgroud)
我假设传递给此方法的两个参数(a和b)总是必须是相同的类型.但令我惊讶的是,我能够将任何类型的参数(甚至原语)传递给方法x,就好像T被擦除为Object,无论传递什么参数.
到目前为止,我发现的唯一解决方法是使用'extends',如下所示:
public static <T, U extends T> void x(T a, U b)
Run Code Online (Sandbox Code Playgroud)
但是虽然我可以忍受它,但这不是我想要的.
有没有办法使用泛型类型来强制方法的所有参数的类型?
TNT*_*TNT 30
如果我理解正确,一种方法是显式指定T的类型,而不是让编译器推断它的类型是最直接的超类,如果两个不同类型的对象作为参数传入.拿这样的东西,例如:
public class Test {
public static void main(String[] args) {
Test.x(5.0, 5); // This works since type is inferred to be Number
Test.<Integer>x(5, 5); // This works since type is stated to be Integer
Test.<Integer>x(5.0, 5); // This doesn't; type is stated to be Integer and Double is passed in
}
public static <T> void x(T a, T b) {
}
}
Run Code Online (Sandbox Code Playgroud)
bar*_*s2x 22
如果我理解你的问题,你想要这个:
x(10, "x");
Run Code Online (Sandbox Code Playgroud)
在编译时失败.现在考虑这样做:
Integer i = 10;
String s = "x";
Object o1 = i;
Object o2 = s;
x(o1, o2);
Run Code Online (Sandbox Code Playgroud)
在这种情况下,它们都是对象 - 相同的类型.我认为没有办法真正实现你想要的东西 - 当你将你的参数转换为Object时,总是可以用两种不同的类型调用它而不会有任何警告/错误.
您可以像这样使用它来指定要使用的类型:
ClassName.<Type>x(obj1, obj2);
Run Code Online (Sandbox Code Playgroud)
它可能是唯一的方法.
Rad*_*def 14
为什么这首先应该是问题对我来说有点模糊.我怀疑你反而误解了类型系统有用的方法.
我们可以做些什么<T> void x(T a, T b)
?嗯,不是很多.身体内部x
,T
是一样的Object
,所以我们只能做一些事情,如呼叫toString
上a
并b
打印它们.
实际上没有任何实际原因 a
,b
必须具有相同的类型.只是他们有一些共同的类型,那个类型Object
或它的子类型.事实上,没有明确的理由说明为什么<T> void x(T a, T b)
实际上需要通用.
a
和b
是因为它无论如何也使用它们.a
以及b
是因为x
是一个void
方法,所以这是一个黑洞.对于具有结果的方法,更典型的是,例如<T> List<T> Arrays.asList(T...)
:
// This will cause a compile error because
// the type inferred must be compatible
// with the return assignment.
List<Integer> r = Arrays.asList(1, 1.0);
Run Code Online (Sandbox Code Playgroud)
或绑定:
// We don't care what the actual types of
// a and b are, just that we can call bar()
// on them.
// Note: this method does not need to be generic.
<T extends Foo> void x(T a, T b) {
a.bar();
a.bar();
}
Run Code Online (Sandbox Code Playgroud)
或者是一种断言某种关系的界限:
// We don't care what the actual types of
// a and b are, just that we can compare
// them to each other.
<T extends Comparable<T>> T max(T a, T b) {
return (a.compareTo(b) < 0) ? b : a;
}
Run Code Online (Sandbox Code Playgroud)
Kon*_*kov 12
调用方法时,可以显式指定类型参数.例如:
<String>x("hello", "world");
Run Code Online (Sandbox Code Playgroud)
但是,如果您没有明确指定type-parameter并且仅依赖于Java的类型推断功能,那么我认为您不仅可以在泛型中使用,而且通常也可以.
方法参数的类型不是具体类型,而是表示一组适用类型的东西(例如,在类的情况下,该集合只能包含一种类型final
).
例如,这种方法:
public void x(Something a) { }
Run Code Online (Sandbox Code Playgroud)
表示一种方法,该参数应该是来自类型集的类型,其与Something
(即Something
及其所有子类型)兼容.
同样适用于泛型.
Gri*_*Dog 10
据推测,您不是以通用方式调用泛型方法,因此它被视为对调用x(Object a, Object b)
.在这个例子中:
public class Test {
static <T> void x(T a, T b) {
}
public static void main(String[] args) {
x(1, 2); // compiles
Test.<String>x(1, 2); // does not compile
Test.<String>x("a", "b"); // compiles
}
}
Run Code Online (Sandbox Code Playgroud)
对x的第一次调用不是一般的,所以它编译.第二个调用等同T
于String
,因此失败因为1
而2
不是Strings
.第三个调用编译因为它正确传入Strings
.
这对我有用
public static <T> void x(T a, T b, Class<T> cls) {
}
Run Code Online (Sandbox Code Playgroud)
现在这个编译
public static void main(String[] args) throws Exception {
x(1, 2, Integer.class);
}
Run Code Online (Sandbox Code Playgroud)
而这不是
public static void main(String[] args) throws Exception {
x(1, "", Integer.class);
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
3500 次 |
最近记录: |