请教一个关于java泛型的语法问题

最近编程序的时候遇到一个java泛型的语法问题,不知道应该怎样实现,麻烦各位大牛帮忙解答:

 

如果父类在类上声明了泛型的话子类可以将泛型类型指定成一个具体类型,比如:

 

class FatherA<T> {

 

public  void test(T t) {

      ;

}

 

}

 

class ChildA extends FatherA<String>{

 @Override

public  void test(String t) {//这里的 t 类型是 java.lang.String

     t.compareTo(t);//编译通过

}

 

}

 

可是如果父类直接在方法前声明了泛型的话子类应该如何指定具体类型呢? 比如:

 

class FatherB {

 

public <T> void test(T t) {

      ;

}

 

}

 

 

class ChildB extends FatherB {

 @Override

public <String> void test(String t) {  //这里的 t 其实是泛型的 并不是java.lang.String类型

     t.compareTo(t);//编译不通过

}

 

}

 

 

请教各位大牛,ChildB 继承的 test方法能指定成java.lang.String类型吗?

 

所有悬赏积分全部送上

7个回答

"强制转换并不是ChildB 想要做的,ChildB 是希望在被实例化了以后能在编译的时候就能限制test函数的参数类型。 " 这违反了面向对象“子类不应该隐藏父类接口”的设计原则,在java中应该是无法做到的。

你考虑一下,假如你可以限制ChildB.getTest只接收String的话,下面的代码能不能通过编译呢?
[code="java"]
FatherA a = factory.getAInstance(); //经过某些复杂条件判断后返回了一个ChildB实例,但这个方法也有可能返回FatherA实例。
a.getTest(new Integer(1));
[/code]
Java在编译期无法知道这个a的具体类型,因此它也不允许(你也不应该)在子类隐藏父类接口或强化父类接口的限制。

public void test(String t)方法中,

你都说这里的 t 其实是泛型的,并不是java.lang.String类型
将t类型转换一下就好了啊,像下面这样:
((java.lang.String) t).compareTo(((java.lang.String) t));

我测试了一下
FatherB的test方法确实可以那么定义
当你的childB实现那个方法的时候,你会看到下面有一个黄色的下划线,提示“The type parameter String is hiding the type String”
很明显你在实现方法的时候的编译器并不会认为你这个是String,并且他会把你的也当做是的作用,在test(String t)实际上也就是test(T t)的意思
所以T根本没有compareTo方法,肯定会报错!
而且你这种写法肯定是不合理的,要不然乱套了
java中一个方法传参数,参数的类型必须是确定的。你这样定义意思就是说,这个方法能够接受任何类型的参数,怎么可能。。。要多态也不能这样子!
FahterA为什么可行?主要是因为你在new这Fahter的子类的时候,时候实例化的子类根本不一样了,比如FahterA那么这new chA出来的是泛型为的子类
当你new FahterA这个new chB出来的是泛型位的子类,那么这些子类chA只能接受参数位String类型的,chB只能接受参数位Integer的,这样方法也不会有什么冲突

解决办法就采用fatherA的方法来解决
如果硬要采用fatherB的话,你应该采用楼上解决办法,强行转换
[code="java"]
@SuppressWarnings("hiding")
@Override
public void test(String t) {
try {
((java.lang.String) t).compareTo((java.lang.String)t);
}catch (Exception e) {
throw new RuntimeException("type does not match.");
}
}[/code]

java中,方法的参数要求必须是“固定类型的”,加引号的原因就是对于泛型来说有点特殊,但是本质没有变化,即实例话对象之后,对象的方法所对应的参数必须是固定类型的。举一个例子:
boolean add(E e) ,这个是ArrayList类的添加方法,这个参数表面看是可变的,但实际上也是有约定的。即Class ArrayList,在实例话对象时需要指定泛型类型,否则E会默认是Object对象。所以要想方法类型动态指定就可以使用该形式。

:(
多看书就行了

呵呵,刚刚研究了一下泛型,你的问题是可以解决的,
class FatherB {
public void test(T t){
System.out.println(t.getClass().getName());
}
}
上面的这种定义方式叫泛型方法

class ChildA extends FatherA{
//记住此处实现实现父类的泛型方法也可以不实现
public void test(T t) {
super.test(t);
}

public static void main(String[] args) {
    GeneMethodImp method = new GeneMethodImp();
    Integer name = new Integer(5);
    method.test(name);//这样就可以根据你传递参数的时候动态的确定类型了
}

[code="java"]
public void getTest(T t); //泛型方法一般会加Super限制.

//子类实现
public void getTest(Object t) { ... }
[/code]

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问