day27
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的更多相关文章
- Spark Streaming揭秘 Day27 Job产生机制
Spark Streaming揭秘 Day27 Job产生机制 今天主要讨论一个问题,就是除了DStream action以外,还有什么地方可以产生Job,这会有助于了解Spark Streaming ...
- python 之路,Day27 - 主机管理+堡垒机系统开发
python 之路,Day27 - 主机管理+堡垒机系统开发 本节内容 需求讨论 构架设计 表结构设计 程序开发 1.需求讨论 实现对用户的权限管理,能访问哪些机器,在被访问的机器上有哪些权限 实 ...
- day27 CRM delete& action& 嵌入CRM
课程目录:deleteactionpop up window嵌入crm项目 权限(未讲)学员交作业发邮件 代码路径:https://github.com/liyongsan/git_class/tre ...
- day27——面向对象的总结、异常处理
day27 面向对象的总结 异常处理 错误的分类 语法错误 if if 2>1 print(222) dic = {"name"; "alex"} 逻辑错 ...
- day27 面向对象
day27 面向对象 目录 day27 面向对象 一.面相对象介绍 1 什么是对象 2 类于对象 二.实现面向对象编程 1 先定义类 2 属性访问 2.1 调用dict方法 2.2 类.属性 3 调用 ...
- day27:异常&反射
目录 认识异常处理 1.程序错误的种类 2.异常的分类 3.AssertionError(断言assert语句失败) 异常处理的基本语法 1.异常处理的基本语法 2.带有分支的异常处理 3.处理 ...
- CMDB资产管理系统开发【day27】:理解RESTful架构
理解RESTful架构 越来越多的人开始意识到,网站即软件,而且是一种新型的软件. 这种"互联网软件"采用客户端/服务器模式,建立在分布式体系上,通过互联网通信,具有高延时(hig ...
- day27、28 二十八、项目:选课系统
选课系统 作业要求 角色:学校.学生.课程.讲师 要求: 1. 创建北京.上海 2 所学校 ----> 创建学校 2. 创建linux , python , go 3个课程 , linux\py ...
- day27:反射和双下方法
1, # 面向对象的三大特性:继承,多态和封装 # 继承: # 单继承: **** # 父类(超类,基类) # 子类(派生类) 派生方法和派生属性 # 子类的对象在调用方法和属性:先用自己的,自己没有 ...
随机推荐
- 【问题解决方案】Dev C++ 无法调试的问题与解决
听翁恺老师课的时候用到一个叫DevC++的编辑器. 学到调试部分的时候,老师的没问题我的报错.我?? 试一试网上查到的方法: 工具 --> 编译选项 --> 代码生成/优化 --> ...
- 爬虫——cookies池的搭建
https://github.com/Python3WebSpider/cookiesPool
- PAT L2-024 部落
https://pintia.cn/problem-sets/994805046380707840/problems/994805056736444416 在一个社区里,每个人都有自己的小圈子,还可能 ...
- Web系统大规模并发——秒杀与抢购 秒杀系统优化与预防措施
电商的秒杀和抢购,对我们来说,都不是一个陌生的东西.然而,从技术的角度来说,这对于Web系统是一个巨大的考验.当一个Web系统,在一秒钟内收到数以万计甚至更多请求时,系统的优化和稳定至关重要.这次我们 ...
- sql之cursor的简介和字符串拆分(split)与游标的使用
字符串拆分(split)与游标的使用 CREATE TABLE Plates ( ,), ) NOT NULL, [BusinessId] INT NOT NULL, ) ),),), SELECT ...
- Kafka-Flume-elasticsearch
a1.sources = kafkaSource a1.channels = memoryChannel a1.sinks = elasticsearch a1.sources.kafkaSource ...
- Ubuntu18.04安装mysql5.7
Ubuntu18.04安装mysql5.7 1.1安装 首先执行下面三条命令: # 安装mysql服务 sudo apt-get install mysql-server # 安装客户端 sudo a ...
- Django的一些操作与视图函数
一 . Django的安装 pip install django==1.14.6 # 后面的数字是django的版本 二 . 通过命令行(cmd)来创建Django项目 1. 切换到保存项目的文件夹 ...
- 引入kaptcha实现验证码验证
1.导入jar包, 可以选择去 https://mvnrepository.com 里面搜索,也可以直接复制下面的代码 2.复制到maven配置文件pom.xml中并保存 <dependency ...
- mysql第一天【mysqldump导出数据和mysql导入数据】
1.使用mysqldump导出数据到本地sql文件 在mysql>bin下执行: 例如: mysqldump -hrm-2ze8mpi5i65429l1qvo.mysql.rds.aliyunc ...