黑马程序员--Java泛型

本文深入探讨Java泛型的概念、好处、内部原理及其在集合、Map和自定义类中的应用,同时展示如何通过反射获取泛型的实际参数,提供一份全面的泛型使用指南。

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

一、泛型的好处

importjava.util.ArrayList;

public class GenericTest {

   public static void main(String[]args) throws Exception{

       //使用泛型限定集合类型为Integer

       ArrayList<Integer> collection1 = newArrayList<Integer>();

       //使用泛型限定集合类型是String

       ArrayList<String> collection2 = newArrayList<String>();

       //判断被泛型限定的两个集合是否指向同一份字节码

       System.out.println(collection1.getClass()==collection2.getClass());

       //通过反射向collection1中加入其它类型的对象

   collection1.getClass().getMethod("add",Object.class).invoke(collection1,"test");

       System.out.println(collection1.get(0));

   }

 

以集合为例:

没有使用泛型任何对象都可以存储进同一个集合中。使用泛型集合,可以将一个集合中的元素指定为一个特定类型,集合中只能存储同一个类型的对象,这样对集合的操作更加安全和方便。

泛型的好处如下:

1、把运行时的异常转到了编译时期。

2、避免了程序员强制类型的转换

二、泛型的内部原理及应用

泛型是提供给Javac编译器使用的,通过限定集合中的输入类型,可以阻止源程序中的非法输入,在运行的过程中,泛型信息会被擦除。通过反射方法跳过编译器,就会使泛型无效。编译器不允许创建泛型变量的数组。即在创建数组实例时,数组的元素不能使用参数化的类型。

参数化类型与原始类型的兼容性,考虑到与以前代码的兼容性,如下代码可以通过编译。

Collection<String>v =new Vector();

参数化类型不考虑类型参数的继承关系,以下两种写法都是错误的:

Vector<String> v =new Vector<Object>();

Vector<Object> v =new Vector<String>();

泛型使用?号作为通配符,如果我们定义变量或者方法时不确定类型是什么,就可以使用?通配符来表示。

通配符的扩展

限定通配符的上边届

//限定为:Number或Number的子类  

正确:Vector<? extendsNumber>x = new Vector<Integer>();

错误:Vector<? extendsNumber>x = new Vector<String>();String不是Number的子类。

正确:Vector<? super Integer>x= new Vector<Number>();必须是Integer的父类,往下最低是Integer本身。

错误:Vector<? super Integer>x= new Vector<Byte>();//Byte与Integer是平级,和Integer没有关系。

泛型和Map集合的一个综合例子:

public class MapTest2 {

    public static void main(String[] args){

       Map<String,String> map = new HashMap<String,String>();

       //添加元素

       map.put("1","Kevin");

       map.put("2","Smart");

       map.put("3","T1");

       //Map中的键转换为Set集合

       Set<Map.Entry<String, String>> keySet =map.entrySet();

       //通过Set集合中的迭代器取出Map中的键值对

       for(Iterator<Map.Entry<String, String>>it=keySet.iterator();it.hasNext();)

       {

           Map.Entry<String, String> entry = it.next();

           //取得键

           System.out.println(entry.getKey());

           //取得value

           System.out.println(entry.getValue());

       }

    }

}

三、自定义泛型

如果类的实例对象中的多处都要用到同一个泛型参数。即这些地方引用的泛型类型要保持同一个实际类型时,这时候就要采用泛型类型的方式进行定义,也就是类级别的泛型,语法格式如下:

publicclass Generic <E> {

  private T fleld;

  public void save(T obj){}

  public T getId(int id){}

}

类级别的泛型是根据引用该类名时指定的类型信息来参数化类型变量的,例如,如下两种方式都可以:

Generic<User> dao = null;

Generic< User > dao =new Generic<User>();

 

四、通过反射获得泛型的实际参数

       通过参数化类型的变量是无法得到实际类型参数的,只能通过将它作为参数的方法才能获取到实际类型参数。

public class Test {

    public static void main(String[] args) throws Exception, SecurityException {

       Method applyMethod = Test.class.getMethod("testVector", Vector.class);

       // 获取方法的泛型参数类型,返回的是个数组

       Type[] types = applyMethod.getGenericParameterTypes();

       // ParameterizedType参数化类型

       ParameterizedType pType = (ParameterizedType) types[0];

       // 获取原型

       System.out.println(pType.getRawType());

       // 获取参数化类型

       System.out.println(pType.getActualTypeArguments()[0]);

    }

    public static void testVector(Vector<Date> v1) {

    }

 

}

 

内容概要:本文档详细介绍了Analog Devices公司生产的AD8436真均方根-直流(RMS-to-DC)转换器的技术细节及其应用场景。AD8436由三个独立模块构成:轨到轨FET输入放大器、高动态范围均方根计算内核和精密轨到轨输出放大器。该器件不仅体积小巧、功耗低,而且具有广的输入电压范围和快速响应特性。文档涵盖了AD8436的工作原理、配置选项、外部组件选择(如电容)、增益调节、单电源供电、电流互感器配置、接地故障检测、三相电源监测等方面的内容。此外,还特别强调了PCB设计注意事项和误差源分析,旨在帮助工程师更好地理解和应用这款高性能的RMS-DC转换器。 适合人群:从事模拟电路设计的专业工程师和技术人员,尤其是那些需要精确测量交流电信号均方根值的应用开发者。 使用场景及目标:①用于工业自动化、医疗设备、电力监控等领域,实现对交流电压或电流的精准测量;②适用于手持式数字万用表及其他便携式仪器仪表,提供高效的单电源解决方案;③在电流互感器配置中,用于检测微小的电流变化,保障电气安全;④应用于三相电力系统监控,优化建立时间和转换精度。 其他说明:为了确保最佳性能,文档推荐使用高质量的电容器件,并给出了详细的PCB布局指导。同时提醒用户关注电介质吸收和泄漏电流等因素对测量准确性的影响。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值