27.01 反射(类的加载概述和加载时机)
 1.类的加载
  当程序要使用某个类时,如果该类还未加载到内存中,系统会通知加载,连接,初始化三步来实现对这个类初始化
 a.加载
  是指将.class文件读入内存中,并创建一个class对象。任何类被使用时系统都会建立一个class对象
 b.连接
  验证:是否有正确的内部结构,并和其他类协调一致
  准备:负责为类的静态成员分配内存,并设置默认初始化值
  解析:将类的二进制数据中的符号引用替换为直接引用
   c.初始化
 2.加载时机
  创建类的实例
  访问类的静态变量,或者静态变量赋值
  调用类的静态方法
  使用反射方式来强制创建某个类或者接口对应的Java.lang.class对象
  初始化某个类的子类
  直接使用Java.exe命令来运行某个主类
27.02 反射(类加载器的概述和分类)
 1.类加载器的概述
  负责将.class 文件加载到内存中,并为之生成对应的class对象
 2.类加载器的分类
  Bootstrap ClassLoader 跟类加载器 负责Java核心类的加载
  Extension ClassLoader 扩展类加载器 负责JRE的扩展目录中jar包的加载
  system ClassLoader 系统类加载器
27.03 反射(反射概述)
 1.反射概述
  Java反射机制是在运行状态中,
  对于任何一个类,都可以知道这个类的所有属性和方法
  对于任何一个对象,都可以调用它的任意一个方法和属性
 2.三种方式
  a.object类的getclass()方法,判断两个对象是否是同一个字节码文件
  b.静态属性class,锁对象
  c.class类中静态方法forName(),读取配置文件
 3.案例

package day27;
import com.heima.bean.Person;
public class day27_03 {
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
Class clazz1 = Class.forName("com.heima.bean.Person");
Class clazz2 = Person.class; Person p =new Person();
Class clazz3 = p.getClass(); System.out.println(clazz1 == clazz2); //判断字节码是否相同
System.out.println(clazz2 == clazz3);
}
}
-------------------------
package day27;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
public class day27_03_eg {
public static void main(String[] args) throws Exception{
//Juicer j =new Juicer(); //购买榨汁机
//j.run(new Apple()); //向榨汁机中放入苹果
//j.run(new Orange()); //向榨汁机中放入苹果 //j.run(new Orange()); //父类引用指向子类对象 //新建config.properties文件,并在里面输入包名.类名
BufferedReader br = new BufferedReader(new FileReader("config.properties"));
Class clazz = Class.forName(br.readLine());
Fruit f = (Fruit) clazz.newInstance();
Juicer j = new Juicer();
j.run(f);
}
} /*class Apple{
public void squeeze(){
System.out.println("榨出一杯苹果汁");
}
}*/
interface Fruit{ //创建接口Fruit
public void squeeze();
}
class Apple implements Fruit{ //继承接口Fruit并重写原接口的方法
public void squeeze(){
System.out.println("榨出一杯橘子汁");
}
}
class Juicer{
/*public void run(Apple a){
a.squeeze();
}
public void run(Orange o){
o.squeeze();
}*/
public void run(Fruit f){
f.squeeze();
}
}

27.04 反射(Class.forName()读取配置文件)
27.05 反射(通过反射获取带参构造方法)
 Constructor
  class类的newInstance()方法是使用该类无参的构造函数创建对象,如果一个类没有无参的构造函数,就不能这样创建的
  可以调用class类的getConstructor(String.class,int.class)方法获取一个指定的构造函数,
  再调用Constructor类的newInstance("张三",20)方法创建

package day27;
import java.lang.reflect.Constructor;
import com.heima.bean.Person;
public class day27_05 {
/**
* Constructor
class类的newInstance()方法是使用该类无参的构造函数创建对象,如果一个类没有无参的构造函数,就不能这样创建的
可以调用class类的getConstructor(String.class,int.class)方法获取一个指定的构造函数,
再调用Constructor类的newInstance("张三",20)方法创建
* @throws Exception
* @throws SecurityException
*/
public static void main(String[] args) throws SecurityException, Exception {
Class clazz = Class.forName("com.heima.bean.Person");
Constructor c = clazz.getConstructor(String.class,int.class);//为什么是这两个.class
//进入com.heima.bean.Person,其构造方法为:public Person(String name, int age),含有String和int
Person p = (Person)c.newInstance("张三",23);
System.out.println(p); }
}

27.06 反射(通过反射获取成员变量并使用)
 Field
  Class.getField(String)方法可以获取类中的指定字段,如果是私有的可以用getDecleadField("name")方法获取,
  再通过set(obj,"李四")方法可以设置指定对象上该字段的值,如果是私有的,需要先调用setAccessible(true)设置访问权限,
  用获取的指定的字段get(obj)可以获取指定对象中该字段的值

package day27;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field; import com.heima.bean.Person;
public class day27_06 {
/**
* Field
Class.getField(String)方法可以获取类中的指定字段,如果是私有的可以用getDecleadField("name")方法获取,
再通过set(obj,"李四")方法可以设置指定对象上该字段的值,如果是私有的,需要先调用setAccessible(true)设置访问权限,
用获取的指定的字段get(obj)可以获取指定对象中该字段的值
* @throws Exception
* @throws SecurityException
*/
public static void main(String[] args) throws SecurityException, Exception {
Class clazz = Class.forName("com.heima.bean.Person");
Constructor c = clazz.getConstructor(String.class,int.class); //获取有参构造。为什么是这两个.class
Person p = (Person)c.newInstance("张三",23); //通过有参构造创建对象 /*Field f = clazz.getField("name"); //获取名字字段
f.set(p,"李四"); //修改名字字段
System.out.println(p); // 无法获取,因为被私有,暴力反射*/ Field f = clazz.getDeclaredField("name"); //暴力反射获取名字字段
f.setAccessible(true); //去除私有权限
f.set(p,"李四"); //修改名字字段
System.out.println(p); }
}

暴力反射

27.07 反射(通过反射获取方法并使用)
 Method
  Class.getMethod(String,Class...)和Class.getDeclaredMethod(String,Class...)方法可以获取该类中的指定方法,
  调用invoke(Object,Object...)可以调用该方法

//前提有另建立的Person类
package day27;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import com.heima.bean.Person;
public class day27_07 {
/**
* Method
Class.getMethod(String,Class...)和Class.getDeclaredMethod(String,Class...)方法可以获取该类中的指定方法,
调用invoke(Object,Object...)可以调用该方法
* @throws Exception
* @throws SecurityException
*/
public static void main(String[] args) throws SecurityException, Exception {
Class clazz = Class.forName("com.heima.bean.Person");
Constructor c = clazz.getConstructor(String.class,int.class); //获取有参构造。给String,int赋值
Person p = (Person)c.newInstance("张三",23); //通过有参构造创建对象 Method m = clazz.getMethod("eat"); //获取eat()方法
m.invoke(p); Method m2 = clazz.getMethod("eat",int.class); //获取eat()方法并给int赋值
m2.invoke(p,10);
}
}

27.08 反射(通过反射越过泛型检查)
 案例演示:
  ArrayList<Integer>的一个对象。在这个集合中添加一个字符串数据,如何实现

package day27;
import java.lang.reflect.Method;
import java.util.ArrayList;
public class day27_08 {
/**
* ArrayList<Integer>的一个对象。在这个集合中添加一个字符串数据,如何实现
* @throws Exception
*/
public static void main(String[] args) throws Exception {
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(111);
list.add(222); Class clazz = Class.forName("java.util.ArrayList"); //获取字节码对象
// Method m = clazz.getMethods("add",Object.class); //放入Object对象
// m.invoke(list, "abc");
System.out.println(list);
}
}

27.09 反射(通过反射写一个通用的设置)
 案例演示:
  public void setProperty(Object obj,String propertyName,Object value){}
  将obj对象中名为propertyname的属性值设置为value。
27.10 反射(练习)
27.11 反射(动态代理的概述和实现)
 1.动态代理
  在程序运行的过程中产生的现象,动态代理其实就是通过反射来生成一个代理
 2.如何生成?
  java.lang.reflect包下提供了一个Proxy类和InvocationHandler接口

/*
* 新建class文件,点击右边的add,实现一个接口InvocationHandler*/
package dongtaidaili;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class MyInvocationHandler implements InvocationHandler {
private Object target;
public InvocationHandler(Object target){
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return null;
} }

MyInvocationHandler

------------Test类--------------
package dongtaidaili;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
UserImp ui = new UserImp();
ui.add();
ui.delete();
}
}
-----------User类----------
package dongtaidaili; public interface User { }
-----------UserImp类-----------
package dongtaidaili;
public class UserImp implements User {
public void add(){
System.out.println("权限校验");
System.out.println("添加功能");
System.out.println("日志记录");
}
public void delete(){
System.out.println("权限校验");
System.out.println("删除功能");
System.out.println("日志记录");
}
}

Test

27.12 反射(模板Template设计模式)
 1.概述:就是定义一个算法的骨架,而将具体的算法延迟到子类中来实现
 2.优缺点:
  优点:使用模板方法模式,在定义算法骨架式,可以很灵活的实现具体的算法,满足用户多变的需求
  缺点:如果算法骨架有修改的话,则需要修改抽象类
27.13 JDK5新特性(自己实现枚举类)
27.14 JDK5新特性(通过enumerate实现枚举类)
27.15 JDK5新特性(枚举类的注意事项)
27.16 JDK5新特性(枚举类的常见方法)
27.17 JDK7新特性(JDK7的6个新特性)
27.18 JDK8新特性(JDK8新特性)

day27的更多相关文章

  1. Spark Streaming揭秘 Day27 Job产生机制

    Spark Streaming揭秘 Day27 Job产生机制 今天主要讨论一个问题,就是除了DStream action以外,还有什么地方可以产生Job,这会有助于了解Spark Streaming ...

  2. python 之路,Day27 - 主机管理+堡垒机系统开发

    python 之路,Day27 - 主机管理+堡垒机系统开发   本节内容 需求讨论 构架设计 表结构设计 程序开发 1.需求讨论 实现对用户的权限管理,能访问哪些机器,在被访问的机器上有哪些权限 实 ...

  3. day27 CRM delete& action& 嵌入CRM

    课程目录:deleteactionpop up window嵌入crm项目 权限(未讲)学员交作业发邮件 代码路径:https://github.com/liyongsan/git_class/tre ...

  4. day27——面向对象的总结、异常处理

    day27 面向对象的总结 异常处理 错误的分类 语法错误 if if 2>1 print(222) dic = {"name"; "alex"} 逻辑错 ...

  5. day27 面向对象

    day27 面向对象 目录 day27 面向对象 一.面相对象介绍 1 什么是对象 2 类于对象 二.实现面向对象编程 1 先定义类 2 属性访问 2.1 调用dict方法 2.2 类.属性 3 调用 ...

  6. day27:异常&反射

    目录 认识异常处理 1.程序错误的种类    2.异常的分类 3.AssertionError(断言assert语句失败) 异常处理的基本语法 1.异常处理的基本语法 2.带有分支的异常处理 3.处理 ...

  7. CMDB资产管理系统开发【day27】:理解RESTful架构

    理解RESTful架构 越来越多的人开始意识到,网站即软件,而且是一种新型的软件. 这种"互联网软件"采用客户端/服务器模式,建立在分布式体系上,通过互联网通信,具有高延时(hig ...

  8. day27、28 二十八、项目:选课系统

    选课系统 作业要求 角色:学校.学生.课程.讲师 要求: 1. 创建北京.上海 2 所学校 ----> 创建学校 2. 创建linux , python , go 3个课程 , linux\py ...

  9. day27:反射和双下方法

    1, # 面向对象的三大特性:继承,多态和封装 # 继承: # 单继承: **** # 父类(超类,基类) # 子类(派生类) 派生方法和派生属性 # 子类的对象在调用方法和属性:先用自己的,自己没有 ...

随机推荐

  1. PAT 7-12 拯救007

    在老电影“007之生死关头”(Live and Let Die)中有一个情节,007被毒贩抓到一个鳄鱼池中心的小岛上,他用了一种极为大胆的方法逃脱 —— 直接踩着池子里一系列鳄鱼的大脑袋跳上岸去!(据 ...

  2. linux 安装ssh以及ssh用法与免密登录

    想要免费登录就是把本地机器的id_rsa_pub的内容放到远程服务器的authorized_keys里面 一.配置yum和hosts文件 配置hosts文件: 命令:vi /etc/hosts 在文件 ...

  3. Oracle 表空间的创建与管理

    Oracle数据库创建之后有一些默认的表空间随之被创建,查询数据字典 dba_data_files 可以得到数据库当前的所有表空间信息. select * from v$tablespace; sel ...

  4. [转帖]system()、exec()、fork()三个与进程有关的函数的比较

    system().exec().fork()三个与进程有关的函数的比较 https://www.cnblogs.com/qingergege/p/6601807.html 启动新进程(system函数 ...

  5. Docker 给 故障停掉的 container 增加 restart 参数

    操作过程见图: 执行的命令比较简单: docker container update --restart=always containername 即可.

  6. python 获取列表中次大的数值.

    需求: 1.写个函数,把一组数字传到函数中,然后取出最大值和次大值. 2.不能使用排序函数. 分析: Q: list = [100,50,60,70,30,45] 怎么从这个列表中取出最大值? A: ...

  7. js中style,currentStyle和getComputedStyle的区别以及获取css样式操作方法

    用js的style只能获取元素的内联样式,内部样式和外部样式使用style是获取不到的. currentStyle可以弥补style的不足(可获取内联样式,内部样式和外部样式),但是只适用于IE. g ...

  8. RedHat Enterprise Linux 6.4使用yum安装出现This system is not registered to Red Hat Subscription Management

    我虚拟机安装的系统是RedHat Enterprise Linux 6.4-i686,是32位的.使用yum命令安装软件时候出现以下错误: This system is not registered ...

  9. 运行pip报错:Fatal error in launcher: Unable to create process using '"'

    参考: https://blog.csdn.net/cjeric/article/details/73518782

  10. sonar结合jenkins

    一.下载jenkins插件 二.系统设置 三.获取token值 4.调整 Jenkins 构建设置