第89节:Java中的反射技术
第89节:
Java
中的反射技术
反射技术是动态的获取指定的类,和动态的调用类中的内容(没有类前就可以创建对象,将对象的动作完成,这就是动态的获取指定的类)。
配置文件把具体实现的类名称定义到配置文件中。
反射技术的作用可以提高程序的扩展性。
Object
类
clone()
用于创建并返回此对象的一个副本
equals(Object obj)
用于指示其他某个对象是否与这个对象“相等”
getClass()
用于返回此Object
的运行时类
hashCode()
用于返回该对象的哈希码值
notify()
用于唤醒在此对象监视器上等待的单个线程
notifyAll()
用于唤醒在此对象监视器上等待的单个线程
notifyAll()
用于唤醒在此对象监视器上等待的所有线程
toString()
用于返回该对象的字符串
要获取某文件中的成员,就要先获取某文件的对象
public class Person{
private String name;
private int age;
public Person(){
super();
}
public Person(String name, int age){
super();
this.name = name;
this.age = age;
}
}
// 定义一个方法获取对象
public static void getClass(){
Person p = new Person();
Class class = p.getClass();
}
public static void getClass(){
String className = "com.dashucoding.Person";
Class cla = Class.forName(className);
Object obj = cla.newInstance();
// 获取创建字节码对象所表示的类的实例
}
pulic T newInstance() throws InstantiationException, IllegalAccessException
创建此Class对象所表示的类的一个实例,对一个带有一个空参数列表的new表达式实例化这个类。
获取构造函数
public static void getConstructorDemo() throws Exception {
String className = "com.dashucodiing.Person";
Class cla = Class.forName(className);
Constructor cons = cla.getConstructor(String.class, int.class);
Object obj = cons.newInstance("dashu",12);
}
获取字段
public static void getFieldDemo() throws Exception {
String className = "com.dashucoding.Person";
Class cla = Class.forName(className);
String fieldName = "age";
//获取字段
Field field = cla.getField(fieldName);
System.out.printlnn(field);
}
getField
public Field getField(String name) thows NoSuchFieldException, SecurityException.
返回一个Field对象。
NoSuchFieldException
如果没有找到带有指定名的字段会报这个错
NullPointerException
如果name为null会报这个错
获取方法
public static void getMethodDemo() throws Exception {
String className = "com.dashucoding.Person";
class cla = Class.forName(className);
String methodName = "show";
Method method = cla.getMethod( methodName, String.class,int.class);
Object obj = cla.newInstance();
method.invoke(obj, "dashu",12;
}
反射技术是这样的以前先有类,才new
对象,现在有了它之后,先new
对象,把创建对象的动作做完,接着才在配置文件中添加哪个类。
当我们使用的类不明确时,通过配置文件告诉应用程序即可。
File configFile = new File("tempfile\\dashu.properties");
if(!configFile.exists()){
configFile.createNewFile();
}
// 读取配置文件
FileReader fr = new FileReader(configFile);
// 为了获取其中的键值信息
Properties prop = new Properties();
prop.load(fr);
for(int x = 1; x<=prop.size(); x++){
String className = prop.getProperty("dashu"+x);
Class cla = Class.forName(className);
class.newInstance();
}
类加载的概述:
如果某个类被这个程序使用时,如果这个类没有被加载到内存中,就会由系统通过加载,连接,初始化三个步骤实现这个类并对其进行初始化。
加载是由内存进行class
文件的读取,简单来说就是class
文件读入内存中,接着创建一个Class
对象,任何类被使用的时候,由系统建立一个Class
对象。(class
文件加载到内存中)
连接:验证,准备,解析
验证内部结构是否正确
准备是否为类的静态成员分配内存,并设置默认的初始化值
解析是将类的二进制数据中的符号引用换为直接引用哦
初始化进行初始化的操作
类加载器的概念
类加载器是把.class
文件加载到内存中,并生成对应的Class
对象。
类加载器的分类有哪些?
Bootstrap ClassLoader
根类加载器
Extension ClassLoader
扩展类加载器
System ClassLoader
系统类加载器
描述其作用:
Bootstrap ClassLoader
根类加载器
路径 jre/lib/rt.jar文件 核心类的加载
Extension ClassLoader
扩展类加载器
路径 jre/lib/ext目录 jar包的加载
System ClassLoader
系统类加载器
jvm启动时加载来自java命令的class文件
反射
源文件 -> 字节码 -> 创建对象
Class cla = Class.forName("类名"); // 读取配置文件
Class cla = Person.class
Person p = new Person(); Class cla = p.getClass();
三种方式:
Class cla = Class.forName("com.dashucoding.Person");
Class cla1 = Person.class;
Person p = new Person();
Class cla2 = p.getClass();
System.out.println(cla = cla1);
System.out.println(cla2 = cla1);
Class.forName()
读取配置文件
public class Demo {
public static void main(String[] args) throws Exception {
Juicer j = new Juicer();
j.run(new Apple());
}
class Apple {
public void squeeze() {
System.out.println();
}
}
class Juicer {
public void run(Apple a) {
a.squeeze();
}
}
}
interface Fruit {
public void squeeze();
}
class Apple implements Fruit {
public void squeeze(){
System.out.println("");
}
}
public static void main(String[] args) throws ClassNotFoundException {
Class cla1 = Class.forName("com.dashucodiing.Person");
Class cla2 = Person.class;
Person p = new Person();
Class cla3 = p.getClass();
}
通过反射获取带参构造方法
package com.dashucoding.demo
public class Demo {
public static void main(String[] args) {
Class clazz = Class.forName("com.dashucoding.bean.Person");
// Person p = (Person) clazz.newInstance();
Constructor c = clazz.getConstructor(String.class,int.class);
Person p = (Person) c.newInstance("dashucoding",12);
System.out.println(p);
}
}
反射获取成员变量
package com.dashucoding.demo
public class Demo {
public static void main(String[] args) {
Class clazz = Class.forName("com.dashucoding.bean.Person");
Constructor c = clazz.getConstructor(String.class,int.class);
Person p = (Person) c.newInstance("dashucoding",12);
// 获取
Field f = clazz.getField("name");
f.set(p, "李四");
// Field f = clazz.getDeclaredField("name");
// f.set(p, "李四");
}
}
获取方法
package com.dashucoding.demo
public class Demo {
public static void main(String[] args) {
Class clazz = Class.forName("com.dashucoding.bean.Person");
Constructor c = clazz.getConstructor(String.class,int.class);
Person p = (Person) c.newInstance("dashucoding",12);
//获取
Method m = clazz.getMethod("say");
m.invoke(p);
Method m2 = clazz.getMethod("say",int.class);
m.invoke(p,12);
}
}
泛型
package com.dashucoding.demo
public class Demo {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
// list.add(1);
Class clazz = Class.forName("java.util.ArrayList");
Method m = clazz..getMethod("方法名", Object.class);
m.invoke(list,"abc");
System.out.println(list);
}
}
propertyName
改属性值
public class Tool {
public void setProperty (Object obj, String propertyName, Object value) throws Exception {
Class clazz = obj.getClass();
Field f = clazz.getDeclaredField(propertyName);
f.setAccessible(true);
f.set(obj, value);
}
}
public static void main(String[] args){
}
class Student {
private String name;
private int age;
...
}
反射
public class Demo {
public void run() {
System.out.println("dashucoding");
}
}
// 配置文件 获取这个名词并加载这个类
com.dashucoding.test.Demo
public static void main(String[] args){
BufferedReader br = new BufferedReader(new FileReader("xxx.properties"));
Class clazz = Class.forName(br.readLine());
Demo demo = (Demo) clazz.newInstance();
demo.run();
}
动态代理
public interface User {
public void add();
public void delete();
}
public class UserImp implements User{
@Override
public void add() {
System.out.println("添加");
}
@Override
public void delete(){
System.out.println("删除");
}
}
public class Test {
public static void main(String[] args){
UserImp ui = new UserImp();
ui.add();
ui.delete();
}
}
动态代理,在程序运行中产生对象。
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h);
new ProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h);
invoke(Object proxy, Method nethod, Object[] args);
public class MyInvocationHandler implements InvocationHandler {
private Object target;
public MyInvocationHandler (Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy,Method method,object[] args) throws Throwable {
method.invoke(target,args);
return null;
}
}
MyInvocationHandler m = new MyInvocationHandler(si);
Student s = (Student)Proxy.newProxyInstance(ui.getClass().getClassLoader(), ui.getClass().getInterfaces(), m);
结言
好了,欢迎在留言区留言,与大家分享你的经验和心得。
感谢你学习今天的内容,如果你觉得这篇文章对你有帮助的话,也欢迎把它分享给更多的朋友,感谢。
作者简介
达叔,理工男,简书作者&全栈工程师,感性理性兼备的写作者,个人独立开发者,我相信你也可以!阅读他的文章,会上瘾!,帮你成为更好的自己。长按下方二维码可关注,欢迎分享,置顶尤佳。
感谢!承蒙关照!您真诚的赞赏是我前进的最大动力!
第89节:Java中的反射技术的更多相关文章
- 第60节:Java中的JavaScript技术
欢迎到我的简书查看我的文集 前言: JavaScript是什么呢?它是一种基于对象和事件驱动的脚本语言,主要是应用于客户端上的.JavaScript它可以做到信息的动态交互,具有交互性,它不允许直接访 ...
- 第68节:Java中的MYSQL运用从小白到大牛
第68节:Java中的MYSQL运用从小白到大牛 前言 学习java必备要求,学会运用!!! 常见关系化数据库 BootStrap是轻量级开发响应式页面的框架,全局css组件,js插件.栅格系统是将页 ...
- Java中的反射和注解
前言 在Java中,反射机制和注解机制一直是一个很重要的概念,那么他们其中的原理是怎么样呢,我们不仅仅需要会使用,更要知其然而之所以然. 目录 反射机制 反射如何使用 注解定义 注解机制原理 注解如何 ...
- 浅说Java中的反射机制(二)
写过一篇Java中的反射机制,不算是写,应该是抄了,因为那是别人写的,这一篇也是别人写的,摘抄如下: 引自于Java基础--反射机制的知识点梳理,作者醉眼识朦胧.(()为我手记) 什么是反射? 正常编 ...
- 第76节:Java中的基础知识
第76节:Java中的基础知识 设置环境,安装操作系统,安装备份,就是镜像,jdk配置环境,eclipse下载解压即可使用,下载tomcat 折佣动态代理解决网站的字符集编码问题 使用request. ...
- java中的反射机制在Android开发中的用处
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反 ...
- 浅说Java中的反射机制(一)
在学习传智播客李勇老师的JDBC系列时,会出现反射的概念,由于又是第一次见,不免感到陌生.所以再次在博客园找到一篇文章,先记录如下: 引用自java中的反射机制,作者bingoideas.(()为我手 ...
- java中动态反射
java中动态反射能达到的效果和python的语法糖很像,能够截获方法的实现,在真实方法调用之前和之后进行修改,甚至能够用自己的实现进行特别的替代,也可以用其实现面向切片的部分功能.动态代理可以方便实 ...
- 【转】.Net中通过反射技术的应用----插件程序的开发入门
转自:http://www.cnblogs.com/winloa/archive/2012/03/25/2416355.html .Net中通过反射技术的应用----插件程序的开发入门 再开始之前,先 ...
随机推荐
- 百度SEO怎么做 影响百度seo排名的因素
现在SEO的最新算法.技巧,希望大家运用这些技巧,都像我一样能够在百度上获得客户: 第一步:了解搜索引擎的工作原理爬——抓——处——排——展 第二步:大家要建立一个整体框架,影响SEO的排名有哪些因素 ...
- Module 的语法
模块功能主要由两个命令构成:export和import.export命令用于规定模块的对外接口,import命令用于输入其他模块提供的功能. 一个模块就是一个独立的文件.该文件内部的所有变量,外部无法 ...
- 面试简单整理之rabbitmq
135.rabbitmq 的使用场景有哪些? 单反单收,单发多收,发布订阅,按路由发送,按主题发送 136.rabbitmq 有哪些重要的角色? Server,Consumer,Producer 13 ...
- Numpy 创建数组
ndarray 数组除了可以使用底层 ndarray 构造器来创建外, 也可以通过以下几种方式来创建. numpy.empty numpy.empty 方法用来创建一个指定形状(shape),数据类型 ...
- txt 修改
[61TECH_HEIBAILIUYI]#gaIcldGcyd7ducFc3deaRaOdAd4dPdMdaenc1chaeedeGcfcfeyd1cedhbidIcXcIdBdbdvdfcvbjdr ...
- Docker安装nexus
一.Nexus3安装 sudo docker search nexus sudo docker pull sonatype/nexus3 sudo docker images sudo docker ...
- MySQL数据库和表名大小写敏感开关的打开办法
背景:window 10系统安装了MySQL57,使用可视化操作工具Navicat Premium 12进行相关操作,一切比较顺利.但在建立数据库和表时,发现大小写命名不敏感.区分大小写输入,保存后默 ...
- Finance版本计划
2.0.0.3 1. 支持自定义报表 提供页面自定义报表,根据存储过程,前端页面传参调用 根据存储过程数据集控制简单样式(数字靠右,列宽) 2. 支持报表公式可修改 定义公式规则(文档) 2.0.0. ...
- 基于STM32L4的开源NBIOT开发资料
基于STM32L4的开源NBIOT开发资料 1. 参考路径:http://www.stmcu.org/module/forum/forum.php?mod=viewthread&tid=615 ...
- Mysql 导入导出表结构与数据
1.导出整个数据库 mysqldump -u用户名 -p密码 数据库名 > 导出的文件名 C:\Users\jack> mysqldump -uroot -pmysql account ...