锁定老帖子 主题:提问:Java5泛型的T.class的获取
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2007-01-29
将A B C类对应的三个对象a b c保存在http session中,并对每个类进行封装 如下 public class AHelper { private A a; private HttpServletRequest request; public AHelper(HttpServletRequest request) { this.request = request; a = (A)request.getSession().getAttribute("a_key"); if(a == null){ a = new A(); } } public A get(){ return a; } } public class BHelper { private B b; private HttpServletRequest request; public BHelper(HttpServletRequest request) { this.request = request; b = (B)request.getSession().getAttribute("b_key"); if(a == null){ b = new B(); } } public B get(){ return b; } } CHelper 类似 现在想用jdk5的范型将上面的3个类合并成一个 如下: public class BaseHelper<T> { private T object = null; private HttpServletRequest request; public BaseHelper(HttpServletRequest request, String key) { this.request = request; object = (T)request.getSession().getAttribute(key); if(object == null){ //怎样获取T.class? } } public T get(){ return object; } } 问题: 怎样获取T.class? 在http://www.blogjava.net/calvin/archive/2006/04/28/43830.html中有介绍获取T.class的方法,但是要求先写一个父类,然后通过继承来实现 这样做需要4个类才能实现:一个父类和3个子类 请问高手们 能不能通过一个类或者有限个类来就解决这类问题? 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2007-01-29
参考 ThreadLocal<T>, 定义一个抽象的 T initValue(); 方法, 然后使用的地方可以用匿名类实现.
|
|
返回顶楼 | |
发表时间:2007-01-29
你不是定义了object,所以只要写object.class不就行了么?
|
|
返回顶楼 | |
发表时间:2007-01-30
springside 里面的一段代码:
package com.j99view.razor.helper; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; /** * Generics的util类, * * @author sshwsfc */ public class GenericsUtils { private static Log log = LogFactory.getLog(GenericsUtils.class); private GenericsUtils() { } /** * 通过反射,获得定义Class时声明的父类的范型参数的类型. * 如public BookManager extends GenricManager<Book> * * @param clazz The class to introspect * @return the first generic declaration, or <code>Object.class</code> if cannot be determined */ public static Class getSuperClassGenricType(Class clazz) { return getSuperClassGenricType(clazz, 0); } /** * 通过反射,获得定义Class时声明的父类的范型参数的类型. * 如public BookManager extends GenricManager<Book> * * @param clazz clazz The class to introspect * @param index the Index of the generic ddeclaration,start from 0. */ public static Class getSuperClassGenricType(Class clazz, int index) throws IndexOutOfBoundsException { Type genType = clazz.getGenericSuperclass(); if (!(genType instanceof ParameterizedType)) { log.warn(clazz.getSimpleName() + "'s superclass not ParameterizedType"); return Object.class; } Type[] params = ((ParameterizedType) genType).getActualTypeArguments(); if (index >= params.length || index < 0) { log.warn("Index: " + index + ", Size of " + clazz.getSimpleName() + "'s Parameterized Type: " + params.length); return Object.class; } if (!(params[index] instanceof Class)) { log.warn(clazz.getSimpleName() + " not set the actual class on superclass generic parameter"); return Object.class; } return (Class) params[index]; } } |
|
返回顶楼 | |
发表时间:2007-01-30
luanma 写道 springside 里面的一段代码:
package com.j99view.razor.helper; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; /** * Generics的util类, * * @author sshwsfc */ public class GenericsUtils { private static Log log = LogFactory.getLog(GenericsUtils.class); private GenericsUtils() { } /** * 通过反射,获得定义Class时声明的父类的范型参数的类型. * 如public BookManager extends GenricManager<Book> * * @param clazz The class to introspect * @return the first generic declaration, or <code>Object.class</code> if cannot be determined */ public static Class getSuperClassGenricType(Class clazz) { return getSuperClassGenricType(clazz, 0); } /** * 通过反射,获得定义Class时声明的父类的范型参数的类型. * 如public BookManager extends GenricManager<Book> * * @param clazz clazz The class to introspect * @param index the Index of the generic ddeclaration,start from 0. */ public static Class getSuperClassGenricType(Class clazz, int index) throws IndexOutOfBoundsException { Type genType = clazz.getGenericSuperclass(); if (!(genType instanceof ParameterizedType)) { log.warn(clazz.getSimpleName() + "'s superclass not ParameterizedType"); return Object.class; } Type[] params = ((ParameterizedType) genType).getActualTypeArguments(); if (index >= params.length || index < 0) { log.warn("Index: " + index + ", Size of " + clazz.getSimpleName() + "'s Parameterized Type: " + params.length); return Object.class; } if (!(params[index] instanceof Class)) { log.warn(clazz.getSimpleName() + " not set the actual class on superclass generic parameter"); return Object.class; } return (Class) params[index]; } } 采用这种方式需要先定义一个带范型参数的父类,然后通过继承才能获得这个T.class,,A B C都需要继承这个父类,所以不能从根本上解决问题。 |
|
返回顶楼 | |
发表时间:2007-01-30
complystill 写道 参考 ThreadLocal<T>, 定义一个抽象的 T initValue(); 方法, 然后使用的地方可以用匿名类实现.
参照ThreadLocal<T>完成如下 public abstract class BaseHelper<T> { private T object = null; private HttpServletRequest request; private String key; public BaseHelper(HttpServletRequest request, String key) { this.request = request; this.key = key; object = (T)request.getSession().getAttribute(key); if(object == null){ object = initValue(); } } public T get(){ return object; } protected abstract T initValue(); } public class BaseHelperTest extends TestCase { private BaseHelper<Product> sm; protected void setUp() throws Exception { HttpServletRequest request = new MockHttpServletRequest(); sm = new BaseHelper<Product>(request, "x_key"){ protected Product initValue(){ return new Product(); } }; } protected void tearDown() throws Exception { super.tearDown(); } /* * Test method for 'com.ecc.beauty.common.page.SessionManager.getAttrbute(String)' */ public void testGet() { assertNotNull(sm.get()); } } 这种方式可以实现一个类代替 A B C等一系列类,但是在每一个用到的地方都写这样一段代码感觉不够优雅 sm = new BaseHelper<Product>(request, "x_key"){ protected Product initValue(){ return new Product(); } }; 不知道有没有更好的解决方式? |
|
返回顶楼 | |
发表时间:2007-01-30
protected abstract T initValue();
sm = new BaseHelper<Product>(request, "x_key"){ protected Product initValue(){ return new Product(); } }; 呵呵 强人 学了一招 闪 |
|
返回顶楼 | |
发表时间:2007-01-30
/汗
你把代码改改,原代码里面的父类改称自己普通类不就OK了?! 你把 Type genType = clazz.getGenericSuperclass(); 改成 Type genType = clazz; 试试 |
|
返回顶楼 | |
发表时间:2007-01-30
我的了解是这样的,所谓T只是用来编写程序时使用的,方便写程序时使用,使能够在编译器发现类型cast的出错,从而减少调试麻烦。类编译后就不会有T这种概念了。所以不存在T.class这个东西。他不是一个类。
编写程序时,使用泛型,就代表了类型的灵活性,所以其class不是死的。要获取他的具体class,只能使用instance.getClass()方法 |
|
返回顶楼 | |
发表时间:2007-01-31
嗯, JAVA的泛形实现采用的是"擦除法",意味着编译后,其实T根本不存在.
所以楼主的泛形代码,基本上和下面这段等效" public class BaseHelper { private Object object = null; private HttpServletRequest request; public BaseHelper(HttpServletRequest request, String key) { this.request = request; object = request.getSession().getAttribute(key); if(object == null){ //怎样获取T.class? // T在哪里? 嘿嘿 } } public T get(){ return object; } } 只不过是在编码时,方便一些. 所以根据形别参数是构造不出具体的对象的. |
|
返回顶楼 | |