- 浏览: 144352 次
- 来自: ...
文章分类
最新评论
-
nocb:
太感谢了, 我调了2天,始终找不到原因,
DataOutputStream writeBytes(String s) 中文乱码--ZT -
jbeduhai:
发贴能成功吗,我执行的怎么是说没有登录呢,前面登录是正常的,发 ...
ZT---httpclient如何保持session会话模拟登录后的操作 -
chwanga:
很详细啊,廓然开朗,感谢楼主
filter servlet 区别--ZT -
JMS_Exception:
xvm03 写道promzaid 写道.net 还是 java ...
Java的字符流和字节流 -
xvm03:
promzaid 写道.net 还是 java java
Java的字符流和字节流
1、不可以用一个本地类型(如int float)来替换泛型.比如List<Integer>不能用List<int>型式
2、运行时类型检查,不同类型的泛型类是等价的(Pair<String>与Pair<Employee>是属于同一个类型 Pair),这一点要特别注意:即如果a instanceof Pair<String>==true的话,并不代表a.getFirst()的返回值是一个String类型
3、泛型类不可以继承Exception类,即泛型类不可以作为异常被抛出
4、不可以定义泛型数组
5、不可以用泛型构造对象,即T first = new T(); 是错误的
6、在static方法中不可以使用泛型,泛型变量也不可以用static关键字来修饰
7、不要在泛型类中定义equals(T x)这类方法,因为Object类中也有equals方法,当泛型类被擦除后,这两个方法会冲突
8、根据同一个泛型类衍生出来的多个类之间没有任何关系,不可以互相赋值,即Pair<Number> p1; Pair<Integer> p2; p1=p2; 这种赋值是错误的。
9、若某个泛型类还有同名的非泛型类,不要混合使用,坚持使用泛型类
Pair<Manager> managerBuddies = new Pair<Manager>(ceo, cfo);
Pair rawBuddies = managerBuddies; 这里编译器不会报错,但存在着严重的运行时错误隐患
泛型与类型转换
Java 5.0引入泛型以后,提高了类型安全性,然而也给编程带来了新的挑战以及新的误区,类型转换就是一个很好的例子。引入泛型以后,对象的类型似乎由两个类型构成:集合类型和参数类型,例如List<Integer> list = new LinkedList<Integer>(),似乎list的类型由List和Integer共同决定。如果真是这样,那么我们如果希望对list进行类型转换,我们该怎么办?是对List转换,还是对Integer转换?要解答上面的问题很简单,编写如下的代码,运行之就可看出端倪:
public static void wrongConversion() {
List < Integer > list = new LinkedList < Integer > ();
list.add( 1 );
list.add( 2 );
list.add( 3 );
// 下面的代码无法编译通过。
// List<Number> wrongList = list;
}
public static void rightConversion() {
LinkedList < Integer > list = new LinkedList < Integer > ();
list.add( 10 );
list.add( 20 );
list.add( 30 );
List < Integer > rightList = list;
for ( int number: rightList) {
System.out.println(number);
}
}
如果你运行上面的代码,你会发现前一个函数根本无法通过编译,而后一个函数不仅编译成功,而且能得到正确结果。这似乎给出了一个结论:对象的类型由集合类型来决定,对对象进行类型转换时也是对集合类型进行转换。事实确实如此!那么为什么会如此呢?
我们可以回忆一下以前我们对参数类型的描述:参数类型不过是一个占位符而已,在编译时,它会被具体的类型代替,同时对添加到集合对象中的数据进行参数检查;如果添加到对象中的数据类型不是指定的具体类型或其子类型,则编译出错;而且,编译以后,该占位符会被移除,运行时你是无法得到任何集合类型中数据的类型信息的。简而言之:
List<String> strings = new LinkedList<String>( );
List<Integer> ints = new LinkedList<Integer>( );
上面的代码在运行时和
List strings = new LinkedList( );
List ints = new LinkedList( );
毫无二致。了解了这一点以后,相信我们对于类型转换也会有更深的理解了。
泛型给我们带来了好处,使我们在编译时就能发现很多错误;然而任何事物都是柄双刃剑,泛型也不例外。泛型的缺点最明显之处就在于类型转换。如果你读过前面的文章,肯定看到过不带参数类型的集合对象转换为带参数类型的集合对象,其实不仅仅如此,这两者之间可以任意转换。这就意味着一点,我们不仅可以对集合类型进行转换,也可以对参数类型进行任意的转换。这似乎与前面的描述不符,因为上面的代码中的List<Number> wrongList = list;根本无法编译通过。确实如此,这行代码确实无法编译通过,不过我们中间做一步处理以后,上面的转换就可以正常编译了:
List mediaList = list;
List<Number> wrongList = mediaList;
由此可见,泛型在给我们带来好处的同时,也带来了无数陷阱,我们在编程时需十分注意,而Java的泛型机制也需要不断更新。
最后和以往一样,以一个拙劣的程序结束本文:
package com.jiang.tiger.chap1;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class GenericReflection {
private static List < Integer > ints = new ArrayList < Integer > ( );
public static void fillList(List < Integer > list) {
for (Integer i : list) {
ints.add(i);
}
}
public static void printList( ) {
for (Integer i : ints) {
System.out.println(i);
}
}
public static void badConversion() {
List < Integer > list = new LinkedList < Integer > ();
list.add( 1 );
list.add( 2 );
list.add( 3 );
fillList(list);
printList();
List badList = list;
badList.add( " bad number " );
badList.add( " wrong idea " );
fillList(list);
printList();
}
public static void badConversion2() {
List list = new LinkedList();
list.add( 1 );
list.add( 2 );
list.add( " bad number " );
List < Integer > badList = list;
badList.add( 12 );
for (Integer i : badList) {
System.out.println(i);
}
}
public static void wrongConversion() {
List < Integer > list = new LinkedList < Integer > ();
list.add( 100 );
list.add( 200 );
list.add( 300 );
// 下面的代码无法编译通过。
// List<Number> wrongList = list;
List mediaList = list;
List < Number > wrongList = mediaList;
wrongList.add( 120.23 );
wrongList.add( 0.1230 );
for (Integer inter : list) {
System.out.println(inter);
}
}
public static void rightConversion() {
LinkedList < Integer > list = new LinkedList < Integer > ();
list.add( 10 );
list.add( 20 );
list.add( 30 );
List < Integer > rightList = list;
for (Integer number: rightList) {
System.out.println(number);
}
}
public static void badReflection() {
List < Integer > myInts = new ArrayList < Integer > ( );
myInts.add( 4 );
myInts.add( 5 );
myInts.add( 6 );
System.out.println( " Filling list and printing in normal way " );
fillList(myInts);
printList( );
try {
List list = (List)GenericReflection. class .getDeclaredField( " ints " ).get( null );
list.add( " Illegal Value! " );
} catch (Exception e) {
e.printStackTrace( );
}
System.out.println( " Printing with illegal values in list " );
printList( );
}
public static void main(String[] args) {
System.out.println( " rightConversion " );
rightConversion();
try {
Thread.sleep( 1000 );
System.out.println( " badConversion " );
badConversion();
} catch (Exception ce) {
ce.printStackTrace();
}
try {
Thread.sleep( 1000 );
System.out.println( " badConversion2 " );
badConversion2();
} catch (Exception ce) {
ce.printStackTrace();
}
try {
Thread.sleep( 1000 );
System.out.println( " wrongConversion " );
wrongConversion();
} catch (Exception ce) {
ce.printStackTrace();
}
try {
Thread.sleep( 1000 );
System.out.println( " badReflection " );
badReflection();
} catch (Exception ce) {
ce.printStackTrace();
}
}
}
发表评论
-
页面弹出登录框如何通过httpclient进行登录
2011-01-04 16:17 1366页面弹出登录框如何通过httpclient进行登录 h ... -
转贴--在Struts2的Action中取得请求参数值的几种方法
2010-10-27 18:33 1213在Struts2的Action中取得请求参数值的几 ... -
jdbc连接
2010-08-02 17:43 745Connection conn = null; ResultS ... -
几个需要仔细阅读的源码
2010-05-19 23:20 730OSGI spring jboss -
listener,filter区别--ZT
2010-04-28 16:05 1695web.xml里面可以配置Filter和Listen ... -
JDK 1.4中存在一个有关编--ZT
2010-04-23 21:30 1059在JDK 1.4中存在一个有关编码的问题。简要描述如下: ... -
Servlet不是单例的--ZT
2010-04-22 20:59 1904Servlet不是单例的.不过一般来说一个servlet只会有 ... -
java 多态的理解--ZT
2010-04-18 00:43 1091如何理解Java多态性?通过类型转换,把一个对 ... -
JAVA 深入学习
2010-04-17 14:37 821java 设计模式:策略模式(内部类的使用),装饰模式(IO) ... -
JAVA和JAVAC 命令行--ZZ
2009-09-27 15:45 881JAVA和JAVAC 命令行 ... -
jbpm工作流入门教程
2009-09-27 11:36 1955jbpm工作流入门教程 ... -
工作流学习-JBPM(一)
2009-09-27 11:25 822展翅飞翔 致力于J2EE与中间件整合方面的研 ... -
详细解析Java中抽象类和接口的区别
2009-03-03 20:38 689详细解析Java中抽象类和 ... -
比较Vector和ArrayList的不同
2009-03-03 20:35 1220――比较Vector和ArrayLi ... -
string,stringbuffer,stringbuilder比较
2009-03-03 20:33 1239出于方便的考虑,我们在进行字符串的内容处理的时候往往会 ... -
java面向对象浅析系列2
2009-03-03 20:21 703java面向对象浅析系列2——抽象类、接口与多继承 有时 ... -
java面向对象浅析系列1
2009-03-03 20:21 740java面向对象浅析系列1 ... -
java1.5线程池简单介绍
2009-03-03 20:17 2272JDK1.5中的线程池使用简介 在多线程大师Doug L ... -
一个JDBC简单连接
2009-03-03 20:04 722一个最基本的JDBC连接: Conn ... -
为什么要使用泛型?
2009-03-03 19:59 1489类型安全的List Java的一 ...
相关推荐
3. **编写泛型类的注意事项** - 定义泛型类时,类型参数写在尖括号内,如 `class TestGen, V>`。 - 实例化泛型对象时,需要指定类型参数的具体类型,如 `TestGen, String> t = new TestGen, String>()`。 - `...
5. **限制与注意事项** - **类型擦除**:泛型信息在运行时不可用,无法在运行时获取泛型类型。 - **不能实例化类型参数**:如 `new T()` 是不允许的。 - **原始类型与泛型**:原始类型(如int、double)不能直接...
Java泛型是Java编程语言中的一个关键特性,...通过这些资料,你可以深入理解Java泛型的各个方面,包括其设计原则、用法以及实际编程中的注意事项。学习并掌握泛型将有助于提升你的Java编程能力,使代码更加优雅、安全。
然而,泛型结构体也有一些需要注意的事项: 1. **装箱与拆箱**:如果泛型结构体需要与引用类型进行交互,可能会涉及装箱(将值类型转换为对象)和拆箱(将对象转换回值类型),这会带来额外的性能成本。 2. **结构体...
#### 三、创建泛型对象的注意事项 在创建泛型对象时,需要注意以下几点: 1. **显式指定类型**:当创建泛型对象时,最好明确指定类型参数`T`的具体类型,以便编译器能够进行类型检查。例如: ```java Pair...
Java泛型研究 Java泛型是Java语言中的一种重要机制,自从Java 1.5版本引入泛型以来,Java开发者可以更方便地编写...开发者需要了解泛型的基本概念、作用、应用和注意事项,以便更好地使用泛型提高代码的质量和安全性。
- 注意事项: - 约束可以用于多个条件:例如同时实现两个接口或继承自某个类。 - 约束可以是接口、基类或特定的类型。 - 约束可以用来实现更复杂的功能,比如对泛型参数进行类型检查等。 - **构造函数约束**: ...
4. `README.md`或类似的文档:解释如何运行示例,以及可能的注意事项。 在实际应用中,还需要理解JDBC(Java Database Connectivity)的基础知识,因为Hibernate是在JDBC之上建立的。此外,了解SQL语言也是必要的,...
6. **注意事项**: - 泛型不支持原始类型(如int、char等),因此在处理这些类型时,通常需要使用对应的包装类(如Integer、Character)。 - 虽然泛型提供了类型检查,但并不能提高运行时性能,其主要作用在于编译...
详细的介绍了集合框架的用法,及其语法规则,剖析了使用的使用注意事项,帮助更牢靠的掌握集合框架的知识及泛型内容。谢谢
- **注意事项**: - 如果定义了泛型却没有使用,IDE如Eclipse会给出警告提示。 - 泛型类型参数可以使用任意非保留关键字,但通常习惯使用`E`、`T`等单个大写字母表示。 #### 三、泛型代码示例 - **示例1**:定义...
- **注意事项:** - 如果没有指定具体的数据类型,默认操作类型为`Object`。 - 泛型类型只能是引用类型,不能是基本数据类型。 - 泛型类型在逻辑上被视为多个不同的类型,但实际上它们都是相同的类型。 **2. 从...
6. **注意事项** - 泛型构造函数中的泛型类型参数只存在于构造函数内部,不会影响整个类的行为。 - 泛型类型参数的约束(如`<E extends Rankable & Serializable>`)确保了传递给构造函数的对象具有特定的能力或...
3. **编写泛型类的注意事项** - 定义泛型类时,类型参数要在尖括号`<>`内声明,如`class TestGen, V>`。 - 实例化泛型类时,必须指定类型参数的具体类型,例如`TestGen, String> t = new TestGen, String>()`。 -...
#### 泛型的注意事项 - **避免在静态上下文中使用泛型**:由于静态成员独立于实例存在,因此在静态方法或静态字段中使用泛型是没有意义的,因为此时类型参数已经被擦除。 - **类型安全性和性能权衡**:虽然泛型提高...
#### 四、编写泛型类的注意事项 1. **定义泛型类**: - 在定义泛型类时,需要在类名后使用 `<...>` 来声明类型参数,如 `class TestGen, V>`。 - 类型参数 `K` 和 `V` 代表的是类型,而不是具体的值。 2. **实例...
5. **泛型的限制与注意事项**: - **类型擦除**:Java的泛型在运行时被擦除,这意味着在运行时无法检测到泛型的类型信息。这是由于历史兼容性原因,因为Java需要保持与早期版本的二进制兼容性。 - **不能实例化...
**使用泛型的注意事项:** - 泛型类的实例化必须指定具体的类型,例如`MyList<int>`,不能创建未指定类型的实例`MyList<>`。 - 泛型约束可以限制类型参数的类型,例如只能是引用类型或数值类型,或者必须实现特定...
#### 六、泛型的实际应用与注意事项 在实际编程中,合理运用泛型可以显著提升代码的可读性、可维护性和性能。但是,过度使用或不当使用泛型也可能导致代码难以理解和调试。因此,在设计泛型结构时,应遵循以下原则...