Java通用方法-如何使其调用专用方法
Java中的泛型方法是否可以根据输入的类型调用特定的其他方法 我尝试了下面的例子,希望能代表这个问题Java通用方法-如何使其调用专用方法,java,generics,Java,Generics,Java中的泛型方法是否可以根据输入的类型调用特定的其他方法 我尝试了下面的例子,希望能代表这个问题 class X { public void pr(Object s) { System.out.println("Object"); } public void pr(String s) { System.out.println("String"); } public <T> void go(T x) { this.pr(x
class X {
public void pr(Object s) {
System.out.println("Object");
}
public void pr(String s) {
System.out.println("String");
}
public <T> void go(T x) {
this.pr(x);
}
public static void main(String[] args) {
String v = "hello";
X x = new X();
// Both print "Object", while I want "String"
x.go(v);
x.<String>go(v);
}
}
X类{
公共无效pr(对象s){
System.out.println(“对象”);
}
公共无效pr(字符串s){
System.out.println(“字符串”);
}
公开作废go(TX){
这是pr(x);
}
公共静态void main(字符串[]args){
String v=“hello”;
X=新的X();
//两者都打印“对象”,而我想要“字符串”
x、 go(v);
x、 go(v);
}
}
我希望go()调用pr(String)。但无论我做什么,pr(Object)都被称为
上面的示例仅用于演示,实际应用要复杂得多
提前感谢。试试这个:
class X {
public void pr(Object s) {
System.out.println("Object");
}
public void pr(String s) {
System.out.println("String");
}
public <T> void go(T x) {
if(x instanceof String){
this.pr((String)x);
} else {
this.pr(x);
}
}
public static void main(String[] args) {
String v = "hello";
X x = new X();
// Both print "Object", while I want "String"
x.go(v);
x.go(new Object());
// x.<String>go(v);
}
}
X类{
公共无效pr(对象s){
System.out.println(“对象”);
}
公共无效pr(字符串s){
System.out.println(“字符串”);
}
公开作废go(TX){
if(字符串的x实例){
这个.pr((字符串)x);
}否则{
这是pr(x);
}
}
公共静态void main(字符串[]args){
String v=“hello”;
X=新的X();
//两者都打印“对象”,而我想要“字符串”
x、 go(v);
x、 go(新对象());
//x.go(v);
}
}
问题是字符串也是一个对象,所以您需要检查它是否是其他对象,这可以通过
instanceof
Java generic是编译时帮助器来完成,Java编译器会去除泛型的类型信息
但你能做到
if (x instanceof String) {
this.pr( (String) x );
}
不幸的是,由于类型擦除,您所描述的内容不可能实现,因此在运行时
T
被视为Object
所以这里选择了pr(Object)
一种可能的解决方案是手动测试所传递数据的类型,并调用正确的方法,而不需要像
public <T> void go(T x) {
if (x instanceof String)
pr((String)x);
else
pr(x);
}
实际上,在这个上下文中,您甚至不需要在go
中使用泛型类型,所以您可以将其重写为
public void go(CanPR x) {
x.pr();
}
不幸的是,你所描述的是不可能的,因为
运行时T的类型擦除被视为对象,因此选择pr(对象)
在这里
不可能。我想,这就是答案。只需在谷歌上搜索“类型擦除”。这里有很多关于它的问题。编译器将该方法编译为
公共void go(Object x)
。因此,声明的x
类型是Object
。此外,我们需要检查x!=ingo
方法中的null
,否则它将抛出一个MethodDumbuityException
。正确,代码中没有处理方法,但请确保它是正确的needed@Rp-这里怎么可能抛出任何异常?如果x==null,则使用s==null调用pr(对象s)。我甚至没听说过这件事exception@kamil09875:您是对的,没有这样的异常,但是如果重载参数不在继承层次结构中,它会抛出类似java.lang的错误:未解决的编译问题:方法不明确?
。糟糕的是,这里它不会抛出那个异常,因为String是Object的一个子类。如果为空,则将调用带参数对象的方法。@Rp-只有一种情况下方法可能不明确,即显式调用方法(空);当您调用方法(var)时,var是一个类型已知的变量,不可能出现歧义。我试着理解你的想法,你能给我一个可能发生这种情况的小例子吗?:)谢谢你的回答。这就解释了,我学习了类型擦除。不幸的是,“instanceof”模式对我不起作用,因为这个东西可以处理的类太多了。我会考虑其他解决方案。@MarcinZukowski不幸的是,这是Java,在其早期版本中,向后兼容性非常重要,因此编译后的cone需要能够在不了解泛型类型的JVM的较旧版本上运行
,因此当时需要进行类型擦除,现在,它是语言的一部分,没有人想删除:/
public void go(CanPR x) {
x.pr();
}