反射技术:

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新特性反射 泛型相关推荐

  1. 黑马程序员Java教程学习笔记(五)

    学习视频:https://www.bilibili.com/video/BV1Cv411372m 如侵权,请私信联系本人删除 文章目录 黑马程序员Java教程学习笔记(五) 日期时间:Date.Sim ...

  2. 2023年黑马程序员Java学习路线图

    2023年Java学科免费学习资源放送40+套课程,超过600小时的内容! 在过去的一年里,为了帮助更多人线上充电,学会更多技能,黑马程序员举办了 150+ 场免费直播公开课,新增精品视频教程 80+ ...

  3. 黑马程序员Java教程学习笔记(三)

    学习视频:https://www.bilibili.com/video/BV1Cv411372m 如侵权,请私信联系本人删除 文章目录 黑马程序员Java教程学习笔记(三) 面向对象:设计对象.注意事 ...

  4. 黑马程序员Java零基础视频教程_下部(P135-P200)

    黑马程序员Java零基础视频教程_下部(P135-P200) 1 多线程 1.1 什么是多线程? 1.2 多线程的并发与并行 1.3 多线程的实现方式 1.3.1 继承Thread类的方式进行实现 1 ...

  5. 黑马程序员Java零基础视频教程_上部(P1-P80)

    黑马程序员Java零基础视频教程_上部(P1-P80) 1. Java入门 1.1 Java学习介绍 1.2 Java人机交互 1.2.1 常用CMD命令 2. Java基础学习 2.1 Java入门 ...

  6. 黑马 程序员——Java基础---IO(下)

    黑马程序员--Java基础---IO(下) ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------ 一.概述 Java除了基本的字节流.字符流之外,还提供 ...

  7. 黑马程序员Java零基础视频教程_下部(P52-P134)

    黑马程序员Java零基础视频教程_下部(P52-P134) 1. 异常 1.1 异常体系介绍 1.2 编译时异常和运行时异常 1.3 异常在代码中的两个作用 1.4 JVM虚拟机默认处理异常的方式 1 ...

  8. 黑马 程序员——Java基础---流程控制

    黑马程序员--Java基础---流程控制 ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------ 一.概述 Java提供了两种基本的流程控制结构:分支结构 ...

  9. 黑马程序员 JAVA WEB 第三节 MYSQL 约束

    这是阿锃总结的第三节黑马程序员JAVA WEB视频的MYSQL约束部分的笔记.希望可以帮助跟我一样正在学习Java web的同学们.我们一起进步.   b_d 若果有同学也想学习黑马程序员Java w ...

  10. 黑马程序员——Java字符流、字节流IO流

    黑马程序员--Java字符流.字节流Io流 ---------------------- <a href="http://www.itheima.com"target=&qu ...

最新文章

  1. 如何支持亿级用户分流实验?AB实验平台在爱奇艺的实践
  2. sql substr切割字符串
  3. 阿里云安装mysql5.6_yum安装mysql 5.6-阿里云开发者社区
  4. 信息系统项目管理师-计算题专题(三)上午计算小题
  5. vfp如何比较两张表的关键字重复_Access开发中建表的基本原理和规范(上)
  6. 学习笔记(20):Python网络编程并发编程-互斥锁与join的区别
  7. React-引领未来的用户界面开发框架-读书笔记(三)
  8. Java8多线程ForkJoinPool:处理异常
  9. TotoiseSVN的上手教程
  10. c语言gets和getchar区别,c语言中关于getchar()、getchar()和gets().......
  11. 企业网络高级技术-VTP中继协议(2)
  12. linux cp通同时新建目录_Linux 新手应该知道的 26 个命令
  13. 视觉传达对中职计算机教育影响,自考视觉传达设计毕业论文:平面设计专业信息化教学资源库建设...
  14. Vue将汉字转为拼音,取出首字母
  15. Win系统 - WIN10 版本号说明
  16. C#中的事件(event)
  17. 七夕表白攻略:教你用自己的专业说情话,成功率100%,我只能帮你们到这里了啊~(程序员系列)
  18. 高等数学期末总复习 DAY6.洛必达求极限、不等式单调性证明、判断拐点、曲率以及曲率半径
  19. 通用验证码识别SDK免费开源
  20. 使用Python对植物大战僵尸学习研究

热门文章

  1. boost/mpl/assert.hpp:189:21: error: unnecessary parentheses in declaration of ‘assert_arg‘ [-Werror=
  2. 塔望3W消费战略全案|绿力冬瓜茶:老品牌的升级保卫战
  3. 沈向洋:为何读论文这么难?
  4. 百度智能云NIRO MAX机器人,打造智慧党建新体验!
  5. NOD32杀毒软件升级ID
  6. Activemq配置文件详解
  7. HDU 5855 Less Time, More profit 最大权闭合子图
  8. NOIP2017提高组广东省成绩
  9. postgresql 10 的并行(parallel)简介
  10. Win10 开启虚拟桌面+投屏