对泛型了解不错,请教大家一个问题
public class Father<T>
{
Class<T> clazz;
public Father()
{
clazz = (Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
public void t()
{
System.out.print(clazz);
}
}
public class Test1 extends Father<java.lang.Integer>
{
public Test1()
{
System.out.println(clazz);
} public static void main(String[] args)
{
Test1 t = new Test1();
}
}
public class Test2{
public Test2()
{
System.out.println(clazz);
} public static void main(String[] args)
{
Father<任意数据类型> a = Father<>(任意数据类型);
}
}上面两个类,那Test1需要在继承Father的时候指定T的类型,然后可以返回,没有问题。
但这样test1就做的比较死板,我希望可以Father<任意数据类型> a = Father<>(任意数据类型),这样可以动态
但Test2这样做的话就会报错java.lang.ClassCastException,就是在clazz = (Class<T>) 做转换的时候出错
请问,应该怎么写才对呢?谢谢!
public class Father<T>
{
Class<T> clazz;
public Father()
{
clazz = (Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
public void t()
{
System.out.print(clazz);
}
}
public class Test1 extends Father<java.lang.Integer>
{
public Test1()
{
System.out.println(clazz);
} public static void main(String[] args)
{
Test1 t = new Test1();
}
}
public class Test2{
public Test2()
{
System.out.println(clazz);
} public static void main(String[] args)
{
Father<任意数据类型> a = Father<>(任意数据类型);
}
}上面两个类,那Test1需要在继承Father的时候指定T的类型,然后可以返回,没有问题。
但这样test1就做的比较死板,我希望可以Father<任意数据类型> a = Father<>(任意数据类型),这样可以动态
但Test2这样做的话就会报错java.lang.ClassCastException,就是在clazz = (Class<T>) 做转换的时候出错
请问,应该怎么写才对呢?谢谢!
解决方案 »
- 求解poi中的characterRun是干什么用的?
- 看完Head.First.Servlets.and.JSP之后。。。关于学struts的问题
- 再发个 阿里巴巴的数据库有多少张表
- 麻烦高手回答,谢谢。没有什么积分啊。
- JBoss4中如何配置JNDI连接Oracle9i数据库
- Hibernate插入的问题
- 怎样使weblogic7支持struts1.1
- ERROR: Error from ejbc: 文件名、目录名或卷标语法不正确。"TestSesMod.ejbgrpx": ERROR: ejbc found errors请问各位大虾是什么原因?谢
- 有谁成功架设Duke在线银行实例,有问题帮我解决一下哦(100分)
- webClient去爬网,js页面调不起来
- 求网上书店的收银和支付宝如何实现思路
- CKeditor放到struts2里,不能上传图片
Test2的main函数怎么没有new关键字的呢?
public static void main(String[] args)
{
Father <T> a = new Father <T>;
a.t();}
}
这样可以不
public class Test2 {
public static void main(String[] args) {
Father<Object> f = new Father<Object>(1);
f.t();
}
}
class Test1<T> extends Father<T> {
public Test1() {
System.out.println(clazz);
} public static void main(String[] args) {
Test1<Test2> t = new Test1<Test2>();
}
}
* 通过反射,获得指定类的父类的泛型参数的实际类型. 如BuyerServiceBean extends DaoSupport<Buyer>
*
* @param clazz clazz 需要反射的类,该类必须继承范型父类
* @param index 泛型参数所在索引,从0开始.
* @return 范型参数的实际类型, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回<code>Object.class</code>
*/
@SuppressWarnings("unchecked")
public static Class getSuperClassGenricType(Class clazz, int index) {
Type genType = clazz.getGenericSuperclass();//得到泛型父类
//如果没有实现ParameterizedType接口,即不支持泛型,直接返回Object.class
if (!(genType instanceof ParameterizedType)) {
return Object.class;
}
//返回表示此类型实际类型参数的Type对象的数组,数组里放的都是对应类型的Class, 如BuyerServiceBean extends DaoSupport<Buyer,Contact>就返回Buyer和Contact类型
Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
if (index >= params.length || index < 0) {
throw new RuntimeException("你输入的索引"+ (index<0 ? "不能小于0" : "超出了参数的总数"));
}
if (!(params[index] instanceof Class)) {
return Object.class;
}
return (Class) params[index];
}试试这个工具类好使不?
http://www.ibm.com/developerworks/cn/java/j-djc02113/
http://www.fh888.com/showfile.html?articleid=51203542FC8943AE9D3B91C7FA4F5507&projectid=5&username=yhn
{
Class<T> clazz; public Father()
{
clazz = (Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
public Father(int pint)
{
clazz = (Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
public void t()
{
System.out.print(clazz);
}
}package com;public class Test1 extends Father<Integer>
{
public Test1()
{
System.out.println(clazz);
} public static void main(String[] args)
{
Test1 t = new Test1();
}
}package com;public class Test2 { public static void main(String[] args) {
Father<Object> f = new Father<Object>(1);
f.t();
}
}
说明:1、test1方法在继承的时候在继承的时候指名数据类型,这样感觉比较死
2、test2方法在实例化的时候指定类型,但会报错java.lang.ClassCastException
谢谢!
package test;import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;public class Father<T> {
Class<T> clazz; public Father() {
// clazz = (Class<T>) ((ParameterizedType) this.getClass()
// .getGenericSuperclass()).getActualTypeArguments()[0];
} public Father(int pint) {
Type genType = this.getClass().getGenericSuperclass();//得到泛型父类
if (!(genType instanceof ParameterizedType)) {
clazz = (Class<T>) genType.getClass();
} else {
clazz = (Class<T>) ((ParameterizedType) this.getClass()
.getGenericSuperclass()).getActualTypeArguments()[0];
}
} public void t() {
System.out.print(clazz);
}
}
Class entityClass;
public Father() {
Type gType = this.getClass().getGenericSuperclass(); //-----这一句,麻烦看看API再看看与你的
//Test2 测试有什么区别?你的Test2测试根本没有经过父类吧;
entityClass = (Class) ((ParameterizedType)gType).getActualTypeArguments()[0];
}
public void t() {
System.out.print(entityClass.getName());
}
}
本身泛型在运行时是不会存在的,即 Type Erasure (Google看头条),至于 getGenericSuperclass()如何获得了运行时的泛型我也不知道怎么弄的,看不到源代码(即使看到也看不懂^_^,JVM...JVM...); 我想了想,看了下 ArrayList 中的源码,其用来存储的数组是 Object 而获取存储的时候是进行了强转的,可以说在运行时还是Object,并且其没有代码(反射等等)操作到那个泛型 E,完全是按照规范的泛型语法在用。最后,我想如果可以按照你Test2测试的那样使用的话,Hibernate Wiki 上的 Generic Data Access Objects 也不会这么写了吧;
运行Test2的时候,Father<Integer> f = new Father<Integer>(1);
不管是什么类型的对象,都输出
java.lang.Class
而不是Father<Integer> f = new Father<Integer>(1); 输出class java.lang.Integer
这个可以解决吗?谢谢!
那个 int 不是泛型啊, 是你构造方法指定的值类型- -||
看错了- -, 你可以看看 TypeVariable 的 API, 看能不能够理解点,我不使用继承,直接那类上的泛型
this.getClass().getParameterTypes() 拿回来的是 T..... TypeVariable 则代表着这个可变的 T
然后在另外一个类里实例化 Father <Integer> f = new Father <Integer>
最后可以在Father中得知T的数据类型是Integer
不知道说清楚了没有
public class Test2<T> {
Class<T> clazz;
@SuppressWarnings("unchecked")
public Test2(Class<T> clazz)
{
this.clazz = clazz;
System.out.println(clazz);
}
@SuppressWarnings("unchecked")
public Test2(int pint)
{
this.clazz = (Class<T>) new Integer(pint).getClass();
System.out.println(clazz);
}
public static void main(String[] args)
{
Test2<Integer> t = new Test2<Integer>(Integer.class);
Test2<String> t1 = new Test2<String>(String.class);
Test2<Integer> t2 = new Test2<Integer>(1);
}
}
public class Top<T> {
public Top() {
for(TypeVariable d : this.getClass().getTypeParameters()) {
System.out.println(d.getName()); // 这个拿不到想要的- -||
}
}
}public class Test {
public void test(){
Top<Integer> top = new Top<Integer>();
}
}
[/CODE]
这是我的测试代码
public class Top<T> {
public Top() {
for(TypeVariable d : this.getClass().getTypeParameters()) {
System.out.println(d.getName());
}
}
}public class Test {
public void test(){
Top<Integer> top = new Top<Integer>();
}
}
* 通过反射,获得指定类的父类的泛型参数的实际类型. 如BuyerServiceBean extends DaoSupport <Buyer>
*
* @param clazz clazz 需要反射的类,该类必须继承范型父类
* @param index 泛型参数所在索引,从0开始.
* @return 范型参数的实际类型, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回 <code>Object.class </code>
*/
@SuppressWarnings("unchecked")
public static Class getSuperClassGenricType(Class clazz, int index) {
Type genType = clazz.getGenericSuperclass();//得到泛型父类
//如果没有实现ParameterizedType接口,即不支持泛型,直接返回Object.class
if (!(genType instanceof ParameterizedType)) {
return Object.class;
}
//返回表示此类型实际类型参数的Type对象的数组,数组里放的都是对应类型的Class, 如BuyerServiceBean extends DaoSupport <Buyer,Contact>就返回Buyer和Contact类型
Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
if (index >= params.length || index < 0) {
throw new RuntimeException("你输入的索引"+ (index <0 ? "不能小于0" : "超出了参数的总数"));
}
if (!(params[index] instanceof Class)) {
return Object.class;
}
return (Class) params[index];
} 试试这个工具类好使不?