黑马程序员----------Java新特性反射 泛型
来源:互联网 发布:知乎日报接口 编辑:程序博客网 时间:2024/05/20 21:46
反射技术:
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,
都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
简单一句话:反射技术可以对类进行解剖。
如何获取Class对象呢?
方式一:
通过对象的getClass方法进行获取。
麻烦在于每次是不是都需要具体的类和该类的对象,以及调用getClass方法。
方式二:
任何数据类型都具备着一个静态的属性class,这个属性直接获取到该类型的对应Class对象。
比第一种简单,不用创建对象,不用调用getClass方法。
但是还是要使用具体的类,和该类中的一个静态属性class完成。
方式三:
这种方式较为简单,只要知道的类的名称即可。
不需要使用该类,也不需要去调用具体的属性和行为。
就可以获取到Class 对象了
获取Class对象的三种方式:
public class ReflectDemo {public static void main(String[] args) throws ClassNotFoundException {getObject_3();}public static void getObject_3() throws ClassNotFoundException {String className = "com.itheima.bean.Person";Class clazz = Class.forName(className);System.out.println(clazz);} //方式二:public static void getObject_2() {Class clazz = Person.class;}//方式一。public static void getObject_1(){Person p = new Person();Class clazz = p.getClass();Person p1 = new Person();Class clazz1 = p1.getClass();System.out.println(p==p1);System.out.println(clazz==clazz1);}
如果指定的类中没有空参数的构造函数。
或者要创建的类对象需要通过指定的构造函数进行初始化。
这时怎么办呢?这时就不能使用newInstance方法了。
既然要通过指定的构造函数进行对象的初始化。
就必须先获取这个构造函数。
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, Exception {createNewObj_2();}public static void createNewObj_2() throws Exception {/* * 如果指定的类中没有空参数的构造函数。 * 或者要创建的类对象需要通过指定的构造函数进行初始化。 * 这时怎么办呢?这时就不能使用newInstance方法了。 * * 既然要通过指定的构造函数进行对象的初始化。 * 就必须先获取这个构造函数。 * */String className = "cn.itcast.bean.Person";Class clazz = Class.forName(className);//获取指定类中的指定的构造函数。Constructor constructor = clazz.getConstructor(String.class,int.class);//创建对象。对象的建立都需要构造函数的初始化。 怎么创建对象可以通过构造器对象完成。Object obj = constructor.newInstance("lisi",20);System.out.println(obj);}/* * 通过Class创建对象。 */public static void createNewObj() throws ClassNotFoundException, InstantiationException, IllegalAccessException{/* * 1,查找并加载Person.class文件进内存,并将该文件封装成Class对象。 * 2,在依据Class对象创建该类具体的实例。 * 3,调用构造函数对对象进行初始化。 *//* * 1,查找并加载指定名字的字节码文件进内存,并被封装成Class对象。 * 2,通过Class对象的newInstance方法创建该Class对应的类的实例。 * 3,调用newInstance()方法会去使用该类的空参数构造函数进行初始化。 * */String className = "cn.itcast.bean.Person";Class clazz = Class.forName(className);Object obj = clazz.newInstance();}
对于一个Javabean可以通过实例化的形式得到对象,也可以通过反射的原理得到对象,并且给对象赋值
最基本的反射方法获取类字节码通过getClass方法获取
Student的类
import java.util.*;public class Student {private String name;private int age;private String sex;private Date birthday;public Student() {}public Student(String name, int age, Date birthday) {this.name = name;this.age = age;this.birthday = birthday;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}public Date getBirthday() {return birthday;}public void setBirthday(Date birthday) {this.birthday = birthday;}}
import java.util.List;import java.lang.reflect.Field;import java.util.Date;import java.text.SimpleDateFormat;import java.util.ArrayList;public class ReflectTest {public static void main(String[] args) throws RuntimeException, Exception {// 反射构造方法设定类中的值Student s = Student.class.getConstructor(new Class[] { String.class, int.class, Date.class }).newInstance(new Object[] { "李四", 32, new Date() });System.out.println(s.getName() + "::" + s.getAge() + "::"+ s.getBirthday());// 反射实例化对象Student stu = Student.class.newInstance();//得到对象中所有field属性//不用getMethods,因为javabean中还有其它继承至Object的方法Field[] fieldName = stu.getClass().getDeclaredFields();for (Field f : fieldName) {String name = f.getName();//得到为set+属性的方法名String methodName = "set" + name.substring(0, 1).toUpperCase()+ name.substring(1);//直接给方法注入参数if (int.class == f.getType()) {stu.getClass().getMethod(methodName, f.getType()).invoke(stu,19);}if (String.class == f.getType()) {stu.getClass().getMethod(methodName, f.getType()).invoke(stu,"张三");}if (Date.class == f.getType()) {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");Date d = (Date) sdf.parse("1988-5-5");stu.getClass().getMethod(methodName, f.getType()).invoke(stu, d);}}System.out.println(stu.getName() + "::" + stu.getAge() + "::"+ stu.getBirthday());}}
数组的的反射
1. 具有相同维数和元素类型的数组属于同一个类型,即具有相同的Class实例对象。
2. 代表数组的Class实例对象的getSuperClass()方法,返回的父类为Object类对应的Class
3. 基本类型的一维数组可以被当做Object类型使用,不能作为Object[]类型使用,不能当做Object[]类型使用,非基本类型的一维数组,既可以当做Object类型使用,又可以当做Object[]类使用
4. 注意区别 Array.asList()方法处理int[]和String[]时的差异
5. Array工具类用于完成对数组的反射操作
private static void printObject(Object obj) { Class clazz = obj.getClass(); if(clazz.isArray()){ int len = Array.getLength(obj); for(int i=0;i<len;i++){ System.out.println(Array.get(obj, i)); } }else{ System.out.println(obj); } }泛型:
JDK1.5以后出现的技术:泛型。
泛型的由来:
1,泛型的出现将运行时期的问题ClassCastException 转移到了编译时期变成了编译失败。
2,泛型的出现避免了类型强制转换的麻烦。
3,泛型技术是用在编译时期的技术。
4,泛型的出现提高了类型的安全性。
泛型的限定:
明确具体类型代表一个类型。
明确?代表所有类型。
下限:? super E:接收E类型或者E的父类型。
当一个类要操作的引用数据类型不确定的时候,可以将该类型定义一个形参。
用到的这类时,有使用者来通过传递类型参数的形式,来确定要操作的具体的对象类型。
意味着在定义这个类时,需要在类上定义形参。用于接收具体的类型实参。
这就是将泛型定义在类上。这就是泛型类。
泛型是提供给java编译器使用的,让编译器挡住程序的非法输入,对于参数化的泛型,getClass返回值和原始类型完全一样。由于编译生成的字节码会去掉泛型的信息,只要跳过编译器,就可以往泛型集合中加入其它类型的数据,如:用反射得到集合,再调用其add方法即可。
collection3.getClass().getMethod("add",Object.class).invoke(collection3, "abc");
ArrayList<E>类定义和ArrayList<Integer>类引用中涉及的术语:
1、整个ArrayList<E>称为泛型类型
2、ArrayList<E>中E称为类型变量或类型参数
3、整个ArrayList<Integer>称为参数化的类型
4、ArrayList<Integer>中的Integer叫类型参数的实例或实际类型参数
5、ArrayList<Integer>中的<>念typeof
6、ArrayList称为原始类型
泛型的例子public class GenericTest {public static void main(String[] args) throws Exception {ArrayList<String> collection2 = new ArrayList();collection2.add("abc");String str = collection2.get(0);Constructor constructor1 = String.class.getConstructor((StringBuffer.class));String str2 = (String) constructor1.newInstance(new StringBuffer("abc"));// 需要产生同样类型的对象System.out.println(str2);ArrayList<Integer> collection3 = new ArrayList();System.out.println(collection3.getClass() == collection2.getClass());collection3.getClass().getMethod("add", Object.class).invoke(collection3, "abc");System.out.println(collection3.get(0));printCollection(collection3);HashMap<String, Integer> maps = new HashMap<String, Integer>();maps.put("ytang", 20);maps.put("yiyi", 23);maps.put("chaox", 24);Set<Map.Entry<String, Integer>> entrySet = maps.entrySet();for (Map.Entry<String, Integer> entry : entrySet) {System.out.println(entry.getKey() + ":" + entry.getValue());}add(3, 5);Number x1 = add(3.5, 3);Object str6 = add(3, "abc");swap(new String[] { "abc", "xyz", "itcast" }, 1, 2);}public static void printCollection(Collection<?> collection) {System.out.println(collection.size());for (Object obj : collection) {System.out.println(obj);}}public static <T> void swap(T[] a, int i, int j) {T tmp = a[i];a[i] = a[j];a[j] = tmp;}private static <T> T add(T x, T y) {return null;}}
- 黑马程序员----------Java新特性反射 泛型
- 黑马程序员——java反射与新特性
- 黑马程序员----java新特性
- 黑马程序员-----JAVA新特性
- 黑马程序员-------Java高级特性--------反射
- 黑马程序员 Java高新技术-jdk1.5新特性和反射基础
- 黑马程序员Java基础第十二章-----JDK1.5新特性介绍,反射机制
- 黑马程序员——Java基础:反射、JDK1.5新特性、正则表达式
- 黑马程序员Java高新__反射
- 黑马程序员-java高新之反射
- 黑马程序员-java基础加强-JDK1.5新特性-泛型
- 黑马程序员---Java基础加强---JDK1.5新特性:泛型
- 黑马程序员:jdk1.5新特性3 (反射)
- 黑马程序员_JDK1.5新特性、枚举、反射
- 黑马程序员_Java语言_反射及jdk新特性
- 黑马程序员—javaSE—反射和新特性
- 黑马程序员---Java中的几个新特性
- 黑马程序员-JAVA jdk1.5新特性
- 应用struts2标签常见的问题
- struts2配置详解(1)
- SilkTest天龙八部系列1-初始化和构造函数
- 托盘图标
- 部分常用的快捷键
- 黑马程序员----------Java新特性反射 泛型
- SilkTest天龙八部系列2-OCR
- Android内存管理(Memory Management), OutOfMemoryError Note
- SilkTest天龙八部系列3-动态父窗口
- ABAP 表格控制(Table Control)和 步循环(STEP-LOOP)
- SilkTest天龙八部系列4-ChildWin
- 鸟哥的私房菜之指令输入与基本指令
- 广播地址计算
- 23种设计模式