Java泛型与反射机制---学习笔记
来源:互联网 发布:java 双亲委派 编辑:程序博客网 时间:2024/04/30 10:29
Java泛型
为什么需要泛型
List list = new ArrayList(); list.add("CSDN_SEU_Cavin"); list.add(100); for (int i = 0; i < list.size(); i++) { String name = (String) list.get(i); //取出Integer时,运行时出现ClassCastException异常 System.out.println("name:" + name); }
list 集合中加入了一个字符类型的值和Integer类型的值[因为list默认类型为Object类型所以这样写合法]
为了解决这个问题,泛型才会出现
泛型的使用
List<String> list = new ArrayList<String>()
这样以后,list.add(100)时,引起编译错误。
通过List<String>
,直接限定了list集合中只能含有String类型的元素,从而在上例中的第5行中,无须进行强制类型转换,因为集合能够记住其中元素的类型信息,编译器已经能够确认它是String类型了。
泛型只在编译阶段有效
命名规则
E - Element (通常代表集合类中的元素)
K - Key
N - Number
T - Type
V - Value
S,U,V etc. – 第二个,第三个,第四个类型参数……
注意,父类定义的类型参数不能被子类继承。
- 也可以同时声明多个类型变量,用逗号分割,例如:
public interface Pair<K, V> { public K getKey(); public V getValue(); } public class OrderedPair<K, V> implements Pair<K, V> { private K key; private V value; public OrderedPair(K key, V value) { this.key = key; this.value = value; } public K getKey() { return key; } public V getValue() { return value; } }
- 创建了OrderedPair对象的两个实例
Pair<String,Integer> p1 = new OrderedPair<String, Integer>("Even", 8); Pair<String,String> p2 = new OrderedPair<String, String>("hello", "world"); //也可以将new后面的类型参数省略,简写为: //Pair<String,Integer> p1 = new OrderedPair<>("Even", 8); //也可以在尖括号内使用带有类型变量的类型变量,例如: OrderedPair<String,Box<Integer>> p = new OrderedPair<>("primes", new Box<Integer>(...));
- 在方法中也可是使用泛型参数,并且该参数的使用范围仅限于方法体内
public class Util { //该方法用于比较两个Pair对象是否相等。 //泛型参数必须写在方法返回类型boolean之前 public static <K, V> boolean compare(Pair<K,V> p1, Pair<K, V> p2) { return p1.getKey().equals(p2.getKey())&& p1.getValue().equals(p2.getValue()); } } Pair<Integer,String> p1 = new Pair<>(1, "apple"); Pair<Integer,String> p2 = new Pair<>(2, "pear"); boolean same = Util.<Integer, String>compare(p1, p2); //实际上,编译器可以通过Pair当中的类型来推断compare需要使用的类型,所以可以简写为: // boolean same= Util. compare(p1, p2);
泛型类的继承
- Integer是Object的子类
- Integer是Number的子类
- Double是Number的子类
- 容易混淆的
/该方法接受的参数类型为Box<Number> public void boxTest(Box<Number> n) { …… } //下面两种调用都会报错 boxTest(Box<Integer>); boxTest(Box<Double>);
虽然Integer和Double都是Number的子类,但是Box与Box并不是Box的子类,不存在继承关系。Box与Box的共同父类是Object。
通配符
public void boxTest(Box<Number> n){ …… }
该方法只能接受 Box<Number>
这种类型的参数,因此用到了通配符
- 为了该方法可以接受Number以及它的任何子类
public void boxTest(Box<? extends Number> n){ …… }
“ ? extends Number ”就代表可以接受Number以及它的子类作为参数。这种声明方式被称为上限通配符(upper bounded wildcard)。
- 希望该方法可以接受Integer,Number以及Object类型的参数
public void boxTest(Box<? super Integer> n){ …… }
“ ? super Integer ”代表可以接受Integer以及它的父类作为参数。这种声明方式被称为下限通配符(lower bounded wildcard)。
- 如果类型参数中既没有extends 关键字,也没有super关键字,只有一个?,代表无限定通配符(Unbounded Wildcards)。
- 通常在两种情况下会使用无限定通配符:
- 如果正在编写一个方法,可以使用Object类中提供的功能来实现
- 代码实现的功能与类型参数无关,比如List.clear()与List.size()方法,还有经常使用的Class
- 通常在两种情况下会使用无限定通配符:
例子:
上限通配符、下限通配符、无限定通配符之间的关系:
java的反射机制
什么是反射机制
反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法
;对于任意一个对象,都能够调用它的任意一个方法和属性;
这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
反射机制能做什么
反射机制主要提供了以下几个功能:
- 在运行时判断任意一个对象所属的类
- 在运行时构造任意一个类的对象
- 在运行时判断任意一个类所具有的成员变量和方法
- 在运行时调用任意一个对象的方法
- 生成动态代理
具体功能实现
反射机制获取类有三种方法,我们来获取Employee类型
//第一种方式: Classc1 = Class.forName("com.app.XXX.Employee"); //第二种方式: //java中每个类型都有class 属性. Classc2 = Employee.class; //第三种方式: //java语言中任何一个java对象都有getClass 方法 Employee e = new Employee(); Classc3 = e.getClass(); //c3是运行时类 (e的运行时类是Employee)
获取所有的方法:getMethods();
Method[] methods = class1.getMethods();
获取所有实现的接口:getInterfaces();
Class<?>[] in = class1.getInterfaces();
获取父类:getSuperclass();
Class<?> superclass = class1.getSuperClass();
获取所有的构造函数:getConstructors();
Constructor<?>[] constructors = class1.getConstructors() ;
获取所有的属性:getDeclaredFields();
Field[] field = class1.getDeclaredFields();
- 可以看出属性的修饰符是: private(会变) , 数据类型:String (会变),名字:id/name(会变)
getDeclaredFields();
和getFields();
的区别getDeclaredFields()
:获得某个类的所有申明的字段,即包括public、private和proteced,但是不包括父类的申明字段。getFields()
:获得某个类的所有的公共(public)的字段,包括父类。
field.setAccessible(true);
===>例:private 类型 无法做出修改 所以设置这个 就可以了- 打破封装 实际上setAccessible是启用和禁用访问安全检查的开关,并不是为true就能访问为false就不能访问
- 由于JDK的安全检查耗时较多.所以通过setAccessible(true)的方式关闭安全检查就可以达到提升反射速度的目的
创建对象:获取类以后我们来创建它的对象,利用newInstance:
//创建类Class<?> class1 = Class.forName("com.app.Person");//创建实例化:相当于 new 了一个对象Object object = class1.newInstance() ;//向下转型Person person = (Person) object ;
总结
- 首先根据传入的类的全名来创建Class对象
- Class c = Class.forName(“className”);//className必须为全名 也就是包含包名,比如:cn.netjava.pojo.UserInfo
- Object obj = c.newInstance();//创建对象的实例
有了对象之后 想要什么信息 就可以得到什么信息了
Class类提供了四个public方法,用于获取某个类的构造方法。
Constructor getConstructor(Class[] params)
根据构造函数的参数,返回一个具体的具有public属性的构造函数(根据指定参数获得public构造方法)Constructor[] getConstructors()
返回所有具有public属性的构造函数数组(获得public的所有构造方法)Constructor getDeclaredConstructor(Class[] params)
根据构造函数的参数,返回一个具体的构造函数(根据指定参数获得public和非public的构造方法)Constructor[] getDeclaredConstructors()
返回该类中所有的构造函数数组(获得public的所有构造方法)
四种获取成员方法的方法
Method getMethod(String name, Class[] params)
根据方法名和参数,返回一个具体的具有public属性的方法(根据方法名 参数类型获得方法)Method[] getMethods()
返回所有具有public属性的方法数组(获取所有的public方法)Method getDeclaredMethod(String name, Class[] params)
根据方法名和参数,返回一个具体的方法(根据方法名和参数类型,获得public和非public的方法)Method[] getDeclaredMethods()
返回该类中的所有的方法数组(不分public和非public属性)
四种获取成员属性的方法
Field getField(String name)
根据变量名,返回一个具体的具有public属性的成员变量(根据变量名得到相应的public变量)Field[] getFields()
返回具有public属性的成员变量的数组(获得类中所有public的方法)Field getDeclaredField(String name)
根据变量名,返回一个成员变量(根据方法名获得public和非public的变量)Field[] getDelcaredField()
返回所有成员变量组成的数组(获取类中所有的public和非public的方法)
“`
利用反射机制能获得什么信息
学习来源
java泛型详解
java的反射机制浅谈
Java 反射 使用总结
- Java泛型与反射机制---学习笔记
- Java反射机制学习笔记
- Java 反射机制-学习笔记
- Java反射机制学习笔记
- java反射机制学习笔记
- 【Java学习笔记】-----反射机制
- [学习笔记]Java反射机制
- Java反射机制学习笔记
- Java反射机制学习笔记
- java学习笔记反射机制
- java学习笔记-反射机制
- JAVA学习笔记--反射机制
- java反射机制学习笔记
- Java反射机制学习笔记
- Java反射机制学习笔记
- java反射机制学习笔记
- Java学习笔记 --- 反射机制
- Java 反射机制学习笔记
- 求格雷码的完整程序源代码
- 继承初始化
- java银联支付
- php中的几个字符串操作函数strtoupper strtolower ucwords ucfirst lcfirst函数
- android获取短信验证码并自动填写
- Java泛型与反射机制---学习笔记
- pl/sql导入存储过程
- mysql子查询中的陷阱
- sql防注入攻击与xss攻击
- PHP的内存泄露问题与垃圾回收
- Don't know how to iterate over supplied "items" in <forEach>
- 美团笔试-人民币
- oj头文件
- Redis Sentinel:集群Failover解决方案(转载)