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, # 面向对象的三大特性:继承,多态和封装 # 继承: # 单继承: **** # 父类(超类,基类) # 子类(派生类) 派生方法和派生属性 # 子类的对象在调用方法和属性:先用自己的,自己没有 ...
随机推荐
- sys模块进度条玩法笔记
#! /user/bin/env python# -*- encoding:utf-8 -*-import time,sys for i in range(31): sys.stdout.write( ...
- Thread类相关方法
线程对象 每一个线程都是和类Thread的实例相关联的.在Java中,有两种基本的使用Thread对象的方式,可用来创建并发性程序. 1.在应用程序需要发起异步任务的时候,只要生成一个Thread对 ...
- 【学亮IT手记】jQuery DOM操作-获取内容和属性
jQuery拥有可操作HTML元素和属性的强大方法. 其中非常重要的部分就是操作DOM的能力. DOM--文档对象模型. <!DOCTYPE html> <html> < ...
- vue中的跨域问题
https://segmentfault.com/a/1190000011072725(原文) 使用vue-axios和vue-resource解决vue中调用网易云接口跨域的问题 注(api很重 ...
- vue-resources&axios
vue-resource vue-resource是Vue.js的一款插件,它可以通过XMLHttpRequest或JSONP发起请求并处理响应. vue-resource特点: 体积小 vue-re ...
- centOS7搭建NFS服务器
借鉴别人这篇博客搭建成功的:http://blog.51cto.com/mrxiong2017/2087001 NFS系统:用来共享文件.图片.视频 准备两个centOS7服务器,一个作NFS ser ...
- 动态SQL1
If标签 动态SQL可以说是MyBatis最强大之处了,这块的应用主要有四个方面if,choose,trim和foreach,接下来先说说if. 顾名思义,if是用来判断条件的,现在假设我们有个需求, ...
- FindBugs-IDEA插件的使用
前言 Findbugs很多人都并不陌生,Eclipse中有插件可以帮助查找代码中隐藏的bug,IDEA中也有这款插件.这个插件可以帮助我们查找隐藏的bug,比较重要的功能就是查找潜在的null指针. ...
- PDO连接mysql数据库加载慢
今天在使用PDO连接mysql操作数据库的时候,发现速度特别慢,都1~2s的时间,不知道怎么回事,后来一步一步排除到new PDO 导致过慢的原因, 这个尴尬了...,调试了半天都没想到问下度娘,才知 ...
- Springmvc架构
框架结构如下图: 架构流程: 1.用户发送请求至前端控制器DispatcherServlet 2.DispatcherServlet收到请求调用HandlerMapping处理器映射器. 3.处理器映 ...