
本教程旨在解决java中因不当使用`vector`而产生的`unchecked`警告。我们将深入探讨如何通过引入泛型和迁移至现代集合框架(如`arraylist`),来提升代码的类型安全性、可读性,并遵循java编程的最佳实践,从而构建更健壮、更易维护的应用程序。
理解unchecked警告及其根源
在Java编程中,unchecked警告通常出现在编译器无法确定类型安全性的操作中,最常见于使用原始类型(raw types)的集合。原始类型是指没有指定泛型参数的集合类,例如直接使用Vector而不是Vector
原始问题中的代码片段使用了java.util.Vector来存储Sroom对象,但在声明Sroomlist时,并未指定其泛型类型:public Vector Sroomlist;。在后续的元素获取中,例如Sroom room = (Sroom) Sroomlist.elementAt(n);,由于Sroomlist是一个原始Vector,elementAt方法返回的是Object类型,因此需要强制转换为Sroom,这正是unchecked警告产生的原因。
现代集合框架与泛型:ArrayList的优势
Java集合框架提供了多种数据结构,其中ArrayList是List接口的一个常用实现,它提供了动态数组的功能。与Vector相比,ArrayList在大多数场景下性能更优,因为它不是线程安全的(除非显式同步),避免了不必要的同步开销。更重要的是,现代Java编程强烈推荐使用泛型(Generics)来声明集合,以确保编译时期的类型安全。
使用泛型,我们可以在声明集合时指定它将存储的元素类型,例如List
立即学习“Java免费学习笔记(深入)”;
- 编译时类型检查:编译器会在编译阶段捕获类型不匹配的错误,而不是等到运行时才发现。
- 消除强制类型转换:从泛型集合中取出的元素已经是其声明的类型,无需手动强制转换。
- 提高代码可读性:代码意图更清晰,开发者一眼就能看出集合中存储的是什么类型的对象。
代码重构:从Vector到ArrayList与泛型
为了解决unchecked警告并优化代码,我们将对原始代码进行以下关键修改:
1. 替换Vector为List和ArrayList
将Dental类中的Sroomlist声明从原始Vector更改为使用泛型的List
修改前:
import java.util.Vector;
public class Dental {
public Vector Sroomlist;
// ...
public Dental(String name, String address, int contact){
// ...
Sroomlist = new Vector();
}
}修改后:
import java.util.ArrayList;
import java.util.List; // 导入List接口
public class Dental {
public List sRoomList; // 使用List接口和泛型
public String name;
public String address;
public int contact;
public Dental(String name, String address, int contact) {
this.name = name;
this.address = address;
this.contact = contact;
this.sRoomList = new ArrayList<>(); // 使用ArrayList初始化,Java 7+可使用菱形运算符
}
} 注意:变量名Sroomlist也被修改为更符合Java命名规范的sRoomList。
2. 更新添加元素操作
ArrayList使用add()方法添加元素,而不是Vector的addElement()。
修改前:
public void addsrooms(Sroom room){
Sroomlist.addElement(room);
}修改后:
public void addsrooms(Sroom room) {
sRoomList.add(room); // 使用add方法
}3. 改进元素遍历与访问
使用泛型后,从集合中获取元素不再需要强制类型转换。同时,Java提供了更简洁的遍历方式,如增强型for循环。
修改前(Dental类中的Details()方法):
// ...
int n = 0;
while (n < Sroomlist.size()){
Sroom room = (Sroom) Sroomlist.elementAt(n); // 需要强制类型转换
n += 1;
// 这里缺少对room的实际操作
}
// ...修改后(推荐使用增强型for循环):
// ...
System.out.println("SURGERY ROOM DETAILS");
if (sRoomList.isEmpty()) {
System.out.println("No surgery rooms added yet.");
} else {
for (Sroom room : sRoomList) { // 使用增强型for循环遍历
room.SRoomDetails(); // 调用Sroom的详情方法
}
}
// ...这里也修正了原始代码中循环体内部没有实际操作room的问题,并增加了空列表判断。
4. 修正类结构与main方法调用
原始代码中Sroom和Composition类被嵌套在Dental类内部,这会导致编译问题。在Java中,通常每个公共类都应在单独的.java文件中。此外,main方法中的Details()调用是一个语法错误,因为它不是静态方法,也不是通过对象实例调用的。
修正类结构: 将Sroom和Composition类定义为独立的公共类。
修正main方法调用:Details()方法是Dental类的成员方法,必须通过Dental类的实例来调用。
修改前(Composition类中的main方法):
public class Composition {
public void main(String[]args){
// ...
Details(); // 错误:Details()不是Composition的成员,也不是静态方法
// ...
}
}修改后:
public class Composition {
public static void main(String[] args) { // main方法必须是静态的
Dental d = new Dental("Dental Surgery ", "abc road", 11889796);
Sroom sr1 = new Sroom(1, " Surgery Room 01");
Sroom sr2 = new Sroom(2, " Surgery Room 02");
Sroom sr3 = new Sroom(3, " Surgery Room 03");
// d.Details(); // 第一次调用,可能在添加房间前,根据需求决定是否需要
d.addsrooms(sr1);
d.addsrooms(sr2);
d.addsrooms(sr3);
d.Details(); // 通过Dental对象实例调用其Details方法
}
}注意:main方法必须是static的。
5. 完善SRoomDetails()方法
原始的SRoomDetails()方法只是打印了标签,没有打印实际数据。
修改前:
public class Sroom {
// ...
public void SRoomDetails(){
System.out.println("Room ID: ");
System.out.println("Room Type: ");
}
}修改后:
public class Sroom {
// ...
public void SRoomDetails(){
System.out.println("Room ID: " + r_id);
System.out.println("Room Type: " + type);
}
}完整重构后的代码示例
为了清晰起










