关于java List的强制转型的理解

本文探讨了 Java 中 List 强制转型的误解与正确解释,通过实例展示了转型过程及潜在风险。

背景:

之前对于涉及到List的强制转型的理解是:      List<Person> personList = (List<Person>) list;  他会检测list中的每一项,如果其中包括非Person类或其子类的就会提示错误.

然而这个想法并不正确.

测试:

两个简单无关系的类.

public class Cat {
	private String name;

	public Cat(String name) {
		super();
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
}

public class Person {

	private String name;

	public Person(String name) {
		super();
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

}

测试代码:

public class TestCastList {

	
	public static void main(String[] args) {
		List list = new ArrayList<Object>();
		list.add(new Person("小红"));
		list.add(new Person("小红2"));
		list.add(new Person("小红3"));
		list.add(new Person("小红4"));
		list.add(new Cat("小花"));
		list.add(new Cat("小花2"));
		list.add(new Cat("小花3"));
		List<Person> personList = (List<Person>) list;
		for (Object object : personList) {
            System.err.println(object);
        }

	}
}

结果:

wei.learn.javaBasic.list.Person@139a55
wei.learn.javaBasic.list.Person@1db9742
wei.learn.javaBasic.list.Person@106d69c
wei.learn.javaBasic.list.Person@52e922
wei.learn.javaBasic.list.Cat@25154f
wei.learn.javaBasic.list.Cat@10dea4e
wei.learn.javaBasic.list.Cat@647e05

结论:

按照我之前的假设,强转判断会出错,并不可能执行.

更为正确的理解是:

1.List的强转是否可以执行取决于声明时的类型和强转的目标类型.  声明时是List  并为设置泛型 所以强转可以进行,但给出了警告提示.

2.list可以添加什么对象取决于声明的类型.

综上 这段逻辑可以正确执行.

PS: 如果personList中的cat对象涉及到了向Person的强转会在运行时出现错误,所以这种编程存在很强的迷惑性.建议不要使用.

      改进在声明最初的list时,提供泛型约束 例如  List<IAnimal> list = new ArrayList<IAnimal>();  面向接口

      这篇博客道理很浅显,  可能是我个人理解的误区.很多人可能并无此疑惑.特此记录.


### Java 中的类型换与转型机制 Java 中的类型换分为两种形式:基本数据类型的换和对象类型的换。这两种机制在实现和使用上各有特点,且都与 Java 的类型系统和运行时安全机制密切相关。 #### 基本数据类型的类型Java 支持两种基本数据类型之间的换:自动类型换和强制类型换。自动类型换发生在将低精度的数据类型赋值给高精度的数据类型时,例如将 `int` 赋值给 `long`。这种换是安全的,不会导致数据丢失,因此 Java 允许它自动进行。相反,当尝试将高精度类型赋值给低精度类型时,必须使用强制类型换,否则编译器会报错,以防止潜在的数据丢失风险。例如,从 `long` 到 `int` 的赋值需要显式地进行类型换。 ```java int a = 10; long b = 100L; b = a; // 可以通过编译 a = (int) b; // 必须进行强制类型换 ``` #### 对象类型的类型换 对象类型的换涉及类的继承关系,主要包括向上转型和向下转型。向上转型是指将子类对象赋值给父类引用,这是自动完成的,不会引发任何问题,因为子类对象本质上也是父类对象的一种。然而,向下转型则相反,即将父类对象赋值给子类引用,这需要显式的类型换,并且存在一定的风险。如果父类对象实际上并不是该子类的实例,则会在运行时抛出 `ClassCastException` 异常。 ```java Object obj = new String("Hello"); String str = (String) obj; // 正确的向下转型 ``` #### 类型换的安全性和 JVM 的角色 Java 虚拟机 (JVM) 在类型换的安全性方面扮演着重要角色。JVM 通过类加载机制确保了不同类加载器加载的相同类被视为不同的类型,从而避免了由于类加载器差异引起的类型混淆问题。当尝试在不兼容的类之间进行换时,JVM 将抛出 `ClassCastException`,以此来维护程序的类型安全。 ```java Object obj = new Integer(10); String str = (String) obj; // 运行时抛出 ClassCastException ``` #### 类型换的应用场景 类型换在 Java 编程中有多种应用场景。例如,在集合框架中,早期版本的 Java 使用 `Object` 类型来存储各种对象,因此从集合中取出对象后需要进行向下转型。此外,类型换也常用于多态性编程,即通过父类引用来调用子类的方法,这要求在特定时刻对父类引用进行向下转型以访问子类特有的方法和属性。 ```java List list = new ArrayList(); list.add("Hello"); String item = (String) list.get(0); // 从集合中取出并转型 ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值