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, # 面向对象的三大特性:继承,多态和封装 # 继承: # 单继承: **** # 父类(超类,基类) # 子类(派生类) 派生方法和派生属性 # 子类的对象在调用方法和属性:先用自己的,自己没有 ...
随机推荐
- 1px实现方案
JS处理 首先,可以通过 window.devicePixelRatio 拿到设备的像素比,然后给 html 标签加上的相应的样式. function retina () { // 高分辨率屏幕处理 ...
- sass变量引入全局
https://www.jianshu.com/p/ab9ab999344b(copy) 本文以Sass做案例,Less的参考,基本配置大同小异. 假如我们有一个Sass的全局变量common.scs ...
- 校园电商项目(1) 基于SSM
第一步:搭好环境 我这里使用Eclipse做本次的项目,tomcat.maven啥的怎么弄就跳过了ヾ(o・ω・)ノ 第二步:创建工程 我们首先创建一个maven项目,选择最后一个,创建完之后发现报错, ...
- MongoDB操作(1)—MongoDB java驱动核心层次结构及操作流程
MongoDB之java驱动学习 预备: 本地运行MongoDB采用默认端口20717: 安装MongoDB驱动: 以下关键步骤. 核心层次结构或步骤: 创建连接池:MongoClient实例. 对于 ...
- 转:Flutter Decoration背景设定(边框、圆角、阴影、形状、渐变、背景图像等)
1 继续关系: BoxDecoration:实现边框.圆角.阴影.形状.渐变.背景图像 ShapeDecoration:实现四个边分别指定颜色和宽度.底部线.矩形边色.圆形边色.体育场(竖向椭圆). ...
- 牛客练习赛13B 幸运数字2
题目链接:https://ac.nowcoder.com/acm/contest/70/B 题目大意: 略 分析: 先DFS求出所有幸运数,然后暴力即可 代码如下: #pragma GCC optim ...
- class面向对象-1
一.基本定义 class cl(object): def __init(self,var) self.var=var def func(self,i) print('%s is in %s'%(i,s ...
- Lodop打印设计、维护、预览、直接打印简单介绍
四者的区别和联系:(其中PRINT_DESIGN打印设计是提供给开发人员的,另外三个可开放给用户)PRINT_DESIGN打印设计:辅助开发人员设计,图形化拖动插入修改等,设计完成后,生成代码拷贝到程 ...
- JavaScript学习笔记之数组(二)
JavaScript学习笔记之数组(二) 1.['1','2','3'].map(parseInt) 输出什么,为什么? ['1','2','3'].map(parseInt)//[1,NaN,NaN ...
- Web API 2 自定义默认Identity Table Name
One of the first issues you will likely encounter when getting started with ASP.NET Identity centers ...