反射与泛型

本文深入探讨Java反射机制的概念及应用,包括如何获取类信息、调用方法和访问属性等核心功能,并介绍泛型的基本原理及其优势。此外,还讨论了通配符的使用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

反射定义
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
反射并没有破坏程序的封装性,为了使代码拥有动态特性而生。
普通用法好比用遥控器操作电视机,而反射就是打开电视机用电路信号去操作电视机。


反射的常用方法:
1,获取类(返回的是Class的一个实例,也是一个对象):
Class.forName("packageName+className");
Object.getClass();
className.class;
2,调用某个对象具体的方法:
 Class cls = Class.forName("android.net.LinkProperties");
 Method meth = cls.getMethod("getRoutes");
 meth.setAccessible(true); //要记得设置权限
 routes = (Collection<RouteInfo>)meth.invoke(property);
3,获取某个对象的属性:
 Field fieldPassword = PrivateField.class.getDeclaredField("password");
        fieldPassword.setAccessible(true);
        PrivateField user = new PrivateField();
        Object password = fieldPassword.get(user);
        System.out.println(password.toString());


主要功能: 
在运行时判断任意一个对象所属的类;
在运行时构造任意一个类的对象;
在运行时判断任意一个类所具有的成员变量和方法;
在运行时调用任意一个对象的方法;
生成动态代理。


泛型定义:
泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。
使用泛型的地方基本都可以用Object实现,但是泛型不需要进行类型转换(输入类型参数时后面相关的都已转换),比Object更加方便。
现在List<Object>, List<String>是两种不同的类型(即便String继承了Object);
在List<String>中加入Object对象会出错,List<Object>可以添加String对象(这里很容易搞反)。

泛型使用实例:
class Gen<T> {
    private T ob; // 定义泛型成员变量
    public Gen(T ob) {
        this.ob = ob;
    }
    public T getOb() {  //调用这个方法时不需要转换类型
        return ob;
    }
    public void setOb(T ob) {
        this.ob = ob;
    }
    public void showType() {
        System.out.println("T的实际类型是: " + ob.getClass().getName());
    }
}


通配符:
◆ 如果你想从一个数据类型里获取数据,使用 ? extends 通配符,这又叫上限操作符。
使用<? extends O>时,说明这是O的一个子类,但不知道子类的具体类型,加入任何类型都可能导致类型不匹配,所以不能往里面加入除null以外的 任何对象;可以确定的是必然是O的子类,所以可以调用O的任意方法,也就是取。
◆ 如果你想把对象写入一个数据结构里,使用 ? super 通配符,又叫下限操作符。
使用<? super O>时,说明这是O的一个父类,所以可以往这个父类里面添加O或者O的子类对象;但是由于不知道父类的具体类型,所以不能取出任何非 Object类型的对象,这往往没什么意义。
◆ 如果你既想存,又想取,那就别用通配符,用普通的泛型就行。


T与?的区别:
T就是将类型固定,而?则不固定,比如下面这个例子:
public class CollectionGenFoo<T extends Collection> {
...
}
这么写就会报错
CollectionGenFoo<Collection> listFoo = new CollectionGenFoo<ArrayList>(new ArrayList());
需要改成:
CollectionGenFoo<ArrayList> listFoo = new CollectionGenFoo<ArrayList>(new ArrayList());
如果把 CollectionGenFoo<T extends Collection> 改成 CollectionGenFoo<? extends Collection>
可以这么写:
CollectionGenFoo<? extends Collection> listFoo = new CollectionGenFoo<ArrayList>(new ArrayList());
本质上两者没有区别,使用的时机不一样。当程序不依赖传入的泛型类型时应该使用?,其他时候使用T(例如返回值是T).







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值