`
vanadiumlin
  • 浏览: 504830 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

Java5泛型的用法,T.class的获取和为擦拭法站台

 
阅读更多
http://www.blogjava.net/calvin/archive/2006/04/28/43830.html
  Java 5的泛型语法已经有太多书讲了,这里不再打字贴书。GP一定有用,不然Java和C#不会约好了似的同时开始支持GP。但大家也清楚,GP和Ruby式的动态OO语言属于不同的意识形态,如果是一人一票,我想大部分的平民程序员更热衷动态OO语言的平白自然。但如果不准备跳槽到支持JSR223的动态语言,那还是看看GP吧。

   胡乱总结泛型的四点作用:
   第一是泛化,可以拿个T代表任意类型。 但GP是被C++严苛的静态性逼出来的,落到Java、C#这样的花语平原里----所有对象除几个原始类型外都派生于Object,再加上Java的反射功能,Java的Collection库没有范型一样过得好好的。

   第二是泛型 + 反射,原本因为Java的泛型拿不到T.class而觉得泛型没用,最近才刚刚学到通过反射的API来获取T的Class,后述。

   第三是收敛,就是增加了类型安全,减少了强制类型转换的代码。这点倒是Java Collection历来的弱项。

   第四是可以在编译期搞很多东西,比如MetaProgramming。但除非能完全封闭于框架内部,框架的使用者和扩展者都不用学习这些东西的用法,否则那就是自绝于人民的票房毒药。C++的MetaProgramming好厉害吧,但对比一下Python拿Meta Programming生造一个Class出来的简便语法,就明白什么才是真正的叫好又叫座。

   所以,作为一个架构设计师,应该使用上述的第2,3项用法,在框架类里配合使用反射和泛型,使得框架的能力更强; 同时采用收敛特性,本着对人民负责的精神,用泛型使框架更加类型安全,更少强制类型转换。
  
   擦拭法避免了Java的流血分裂 :
    大家经常骂Java GP的擦拭法实现,但我觉得多亏于它的中庸特性---如果你用就是范型,不用就是普通Object,避免了Java阵营又要经历一场to be or not to be的分裂。
    最大的例子莫过Java 5的Collection 框架, 比如有些同学坚持认为自己不会白痴到类型出错,而且难以忍受每个定义的地方都要带一个泛型定义List〈Book〉,不用强制类型转换所省下的代码还不够N处定义花的(对了,java里面还没有tyepdef.....),因此对范型十分不感冒,这时就要齐齐感谢这个搽拭法让你依然可以对一个泛型框架保持非泛型的用法了...

   通过反射获得 T.class:
  
    不知为何书上不怎么讲这个,是差沙告诉我才知道的,最经典的应用见Hibernate wiki的Generic Data Access Objects, 代码如下:
abstract public class BaseHibernateEntityDao<T> extends HibernateDaoSupport {
private Class<T> entityClass;
public BaseHibernateEntityDao() {
        entityClass =(Class<T>) ((ParameterizedType) getClass()
                                .getGenericSuperclass()).getActualTypeArguments()[0];
    }
public T get(Serializable id) {
        T o = (T) getHibernateTemplate().get(entityClass, id);
}
}

  精华就是这句了:
Class<T> entityClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];

  泛型之后,所有BaseHibernateEntityDao的子类只要定义了泛型,就无需再重载getEnttityClass(),get()函数和find()函数,销益挺明显的,所以SpringSide的Dao基类毫不犹豫就泛型了。

  不过擦拭法的大棒仍在,所以子类的泛型语法可不能乱写,最正确的用法只有:
  
public class BookDao extends BaseHibernateEntityDao<Book>


发表于 2006-04-28 16:35 江南白衣 阅读(41822) 评论(24)  编辑  收藏

评论
# re: Java5泛型的用法,T.class的获取和为擦拭法站台
Strategy Pattern with Generics

http://www.javaspecialists.co.za/archive/newsletter.do?issue=123&locale=en_US

贴一篇用泛型的方式实现策略模式...
theone 评论于 2006-04-28 17:27  回复  更多评论   
# re: Java5泛型的用法,T.class的获取和为擦拭法站台
I encounter same problem with http://forum.java.sun.com/thread.jspa?threadID=684429&messageID=3985573

how about this?
faint 评论于 2006-04-28 21:48  回复  更多评论   
# re: Java5泛型的用法,T.class的获取和为擦拭法站台
package test;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

import junit.framework.TestCase;

class TClass<T> {
}

class GoodClass<T> extends TClass<String> {
public ParameterizedType getClassT() {
return (ParameterizedType) getClass().getGenericSuperclass();
}
}

class BadClass<T> extends TClass<T> {
public ParameterizedType getClassT() {
return (ParameterizedType) getClass().getGenericSuperclass();
}
}

public class GenericsTest extends TestCase {

private void print(Type[] targs) {
System.out.print("actual type arguments are:");
for (int j = 0; j < targs.length; j++) {
System.out.print(" instance of " + targs[j].getClass().getName() + ":");
System.out.println(" (" + targs[j] + ")");
}
}

public void testGoodClass() throws Exception {
ParameterizedType type = new GoodClass<String>().getClassT();
Type[] types = type.getActualTypeArguments();
print(types);

assertEquals(TClass.class, type.getRawType());
assertEquals(String.class, types[0]);
}

public void testBadClass() throws Exception {
ParameterizedType type = new BadClass<String>().getClassT();
Type[] types = type.getActualTypeArguments();
print(types);

assertEquals(TClass.class, type.getRawType());
assertEquals(String.class, types[0]);
}
}
分享到:
评论

相关推荐

    Java泛型的用法及T.class的获取过程解析

    Java泛型的用法及T.class的获取过程解析 Java泛型是Java编程语言中的一种重要特性,它允许开发者在编写代码时指定类型参数,从而提高代码的灵活性和可读性。本文将详细介绍Java泛型的用法 及T.class的获取过程解析...

    4.java泛型的限制.zip

    4.java泛型的限制.zip4.java泛型的限制.zip4.java泛型的限制.zip4.java泛型的限制.zip4.java泛型的限制.zip4.java泛型的限制.zip4.java泛型的限制.zip4.java泛型的限制.zip4.java泛型的限制.zip4.java泛型的限制.zip...

    2.java定义泛型类.zip

    2.java定义泛型类.zip2.java定义泛型类.zip2.java定义泛型类.zip2.java定义泛型类.zip2.java定义泛型类.zip2.java定义泛型类.zip2.java定义泛型类.zip2.java定义泛型类.zip2.java定义泛型类.zip2.java定义泛型类.zip...

    1.java泛型定义.zip

    1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1....

    3.java实例化泛型类.zip

    3.java实例化泛型类.zip3.java实例化泛型类.zip3.java实例化泛型类.zip3.java实例化泛型类.zip3.java实例化泛型类.zip3.java实例化泛型类.zip3.java实例化泛型类.zip3.java实例化泛型类.zip3.java实例化泛型类.zip3....

    [Java泛型和集合].(Java.Generics.and.Collections).文字版

    **Java泛型** 是自Java 5引入的一种机制,它允许在类、接口和方法声明中使用类型参数,以实现更强大的类型检查和更少的类型转换。泛型的主要优点包括: 1. **类型安全**:编译时可以检查错误,避免了运行时...

    Java泛型使用详细分析.pdf

    在本文中,我们将详细介绍 Java 泛型的使用方法和实现原理。 一、泛型的简介 泛型是 Java 5 中引入的一种语言特性,旨在解决类型安全问题。在 Java 中,泛型可以应用于集合、类、接口和方法中。泛型的主要目的是...

    Java1.5泛型指南中文版.doc

    在Java 1.5中引入的泛型是一种强大的类型安全机制,它允许开发者编写能够处理不同类型数据的类和方法,同时保持代码的类型安全性。通过使用泛型,开发者可以避免在运行时进行显式的类型转换,从而提高代码的可读性和...

    Java1.5泛型指南中文版(Java1.5Gene....pdf

    本资源为 Java 1.5 泛型指南中文版的详细笔记,涵盖了泛型的基础知识、泛型类、泛型方法、通配符、擦除和翻译、类型安全、类型参数、实际类型参数、擦除、翻译、转型和 instanceof、数组、Class Literals as Run-...

    Java泛型技术之发展.pdf

    Java泛型是Java编程语言中的一个关键特性,它在2004年随着Java SE 5.0的发布而引入,极大地增强了代码的类型安全性和重用性。本篇文章将深入探讨Java泛型的发展历程、核心概念以及其在实际开发中的应用。 1. **发展...

    Java中的泛型简析实战.zip

    Java中的泛型简析实战Java中的泛型简析实战Java中的泛型简析实战Java中的泛型简析实战Java中的泛型简析实战Java中的泛型简析实战Java中的泛型简析实战Java中的泛型简析实战Java中的泛型简析实战Java中的泛型简析实战...

    java-泛型-面试题.docx

    java-泛型-面试题.docx

    [Java泛型和集合].

    Java泛型和集合是Java编程语言中的核心特性,它们极大地提高了代码的类型安全性和可读性,同时也简化了集合操作。本资料主要基于Maurice Naftalin和Philip Wadler合著的《Java泛型和集合》进行讨论。 首先,我们要...

    Java泛型单元试题.html

    精选java关于泛型的原理,应用和面试题,包含所有泛型考点。例如,泛型的概念,类型,实例化,容易混淆的用法。每一道题附上答案,方便理解考试要点。

    java泛型实例讲解代码.rar

    Java泛型是Java编程语言中的一个关键特性,它在2004年随着JDK 5.0的发布被引入,极大地增强了...这个压缩包可能包含了各种示例,如泛型类、泛型方法、边界限制等,通过这些实例,你可以亲手实践并掌握Java泛型的用法。

    Java中的泛型方法演示代码

    在这个“Java中的泛型方法演示代码”中,我们可以期待看到如何在Java中定义和使用泛型方法的实例。 首先,泛型方法的基本语法是在方法声明前加上尖括号`&lt;&gt;`,并在其中定义一个或多个类型参数。例如: ```java ...

Global site tag (gtag.js) - Google Analytics