我们先来个示例

用户类

package com.lf.entity;

import com.lf.annotation.SetProperty;
import com.lf.annotation.SetTable; public class UserEntity {
private String userName;
private int userAge;
private final int money = 10000; public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public int getUserAge() {
return userAge;
}
public void setUserAge(int userAge) {
this.userAge = userAge;
}
//借钱方法
public int getMoney(){
System.out.println("你借了 " + money + "元!");
return money;
}
//还钱方法,单个参数
public void repay(int money){
System.out.println("你还了 " + money + "元!");
}
//还钱方法,多个参数
public void repay(String userName,int money){
System.out.println(userName+ " 还了 " + money + "元!");
}
}

测试类

  //反射调用方法获取返回值

  1)获取类对象Class

  2)根据类对象Class获取构造器getConstructor(类<?>... parameterTypes)

  3)然后用Constructor. newInstance(Object... initargs)获取实例;作为参数传入5)

  4 )根据类对象Class获取方法getMethod(String name, 类<?>... parameterTypes)

  5)然后用Method.invoke执行方法invoke(Object obj, Object... args)

package com.lf.test;

import java.lang.reflect.Method;

import com.lf.entity.UserEntity;

public class Reflection {

public static void main(String[] args) throws Exception {
Class<?> userClass = Class.forName("com.lf.entity.UserEntity");
UserEntity userEntity = (UserEntity) userClass.newInstance(); //第一种方法:获取对象,直接通过对象调用方法
System.out.println("第一次借钱:");
int money = userEntity.getMoney();
System.out.println("实际拿到钱为: " + money);
System.out.println("------------------------分割线--------------"); //第二种方法:通过方法名获取方法,执行方法
//(无参的示例:借钱)
System.out.println("第二次借钱:");
Method getMoney = userClass.getMethod("getMoney");//得到方法对象
Object money2 = getMoney.invoke(userEntity);//调用借钱方法,得到返回值
System.out.println("实际拿到钱为:" + money2);
System.out.println("------------------------分割线---------------"); //(单个参数的示例:还钱)
System.out.println("第一次还钱:");
Method repay1 = userClass.getMethod("repay",int.class);//得到方法对象,有参的方法需要指定参数类型
repay1.invoke(userEntity,3000);//执行还钱方法,有参传参
System.out.println("------------------------分割线---------------");
//(多个参数的示例:还钱)
System.out.println("第二次还钱:");
Method repay2 = userClass.getMethod("repay", String.class,int.class);//得到方法对象,有参的方法需要指定参数类型
repay2.invoke(userEntity,"小飞",5000);//执行还钱方法,有参传参 }
}

再说说面向对象中的反射机制

* 框架:半成品软件。可以在框架的基础上进行软件开发,简化编码

* 反射:将类的各个组成部分封装为其他对象(对象数组),这就是反射机制

*Java反射机制的由来:1.技术驱动。2.Java老大哥不要面子嘛??

类名本身明明就是一个字符串,我想通过对字符串的控制来创建一系列不同的对象,怎么办?不好意思,java语法本身是不提供这个功能的,但是JavaScript就可以定义变量即为对象,且可以为该对象随意添加属性。为了维护java高大上的荣誉,自然是要污蔑javascript的方式是导致js代码混乱的根源之一。可是实际需要这种方法的时候,对javascript批量生产不同object方式又羡慕嫉妒恨,在没有办法的情况下,创立了反射机制,这样就能通过字符串找到需要的类并进行不同对象批量生成。java优雅地再次在功能上碾压了javascript,从此人人都又高兴了起来。

Java中的反射细节

* 获取Class对象的方式:

1.源代码阶段:

    Class.forName("全类名"):将字节码文件加载进内存,返回Class对象

* 多用于配置文件,将类名定义在配置文件中。读取文件,加载类

2. Class类对象阶段

    类名.class:通过类名的属性class获取

* 多用于参数的传递--被传者

3. Runtime运行阶段

    对象.getClass():getClass()方法在Object顶级类中定义着。

* 多用于对象的获取字节码的方式

结论:

同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取的Class对象都是同一个。

* Class对象功能:

获取功能:

1. 获取成员变量们

* Field[] getFields() :获取所有public修饰的成员变量

* Field getField(String name)获取指定名称的 public修饰的成员变量

* Field[] getDeclaredFields() 获取所有的成员变量,不考虑修饰符

* Field getDeclaredField(String name)

2. 获取构造方法们

//类<?>:比如String.class

* Constructor<?>[] getConstructors()

* Constructor<T> getConstructor(类<?>... parameterTypes)

* Constructor<T> getDeclaredConstructor(类<?>... parameterTypes)

* Constructor<?>[] getDeclaredConstructors()

3. 获取成员方法们:

* Method[] getMethods()

* Method getMethod(String name, 类<?>... parameterTypes)

* Method[] getDeclaredMethods()

* Method getDeclaredMethod(String name, 类<?>... parameterTypes)

4. 获取全类名

* String getName()

*封装的对象

*Field:成员变量

* 操作:

// Object obj :Field对象所在类对象的引用名称

1. 设置值

* void set(Object obj, Object value)

2. 获取值

* get(Object obj)

3. 忽略访问权限修饰符的安全检查

* setAccessible(true):暴力反射

* Constructor:构造方法

* 创建对象:

* T newInstance(Object... initargs)

* 如果使用空参数构造方法创建对象,操作可以简化:Class对象的newInstance方法

* Method:方法对象

// Object obj :Method对象所在类对象的引用名称

* 执行方法:

* Object invoke(Object obj, Object... args)

* 获取方法名称:

* String getName:获取方法名

【注释】:

类<?>... parameterTypes:比如String.class(多个)

Object obj :对象的引用,即实例名称

Object... args :实参(多个)

反射是框架的灵魂

* 需求:写一个"框架",不能改变该类的任何代码的前提下,可以帮我们创建任意类的对象,并且执行其中任意方法(以后只需改配置文件即可)

* 实现:

1. 定义实体类

2. 配置文件xxx.properties

3. 定义框架类

* 步骤:

1. 将需要创建的对象的全类名和该类下要执行的方法定义在配置文件中

2. 在框架类中加载读取配置文件

3. 在框架类中使用反射技术来加载类文件进内存,即获取Class

4. 同上…

浅谈Java反射与框架的更多相关文章

  1. 浅谈Java的集合框架

    浅谈Java的集合框架 一.    初识集合 重所周知,Java有四大集合框架群,Set.List.Queue和Map.四种集合的关注点不同,Set 关注事物的唯一性,List 关注事物的索引列表,Q ...

  2. 浅谈java类集框架和数据结构(2)

    继续上一篇浅谈java类集框架和数据结构(1)的内容 上一篇博文简介了java类集框架几大常见集合框架,这一篇博文主要分析一些接口特性以及性能优化. 一:List接口 List是最常见的数据结构了,主 ...

  3. 浅谈java反射机制

    目录 什么是反射 初探 初始化 类 构造函数 属性 方法 总结 思考 什么是反射 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意 ...

  4. 浅谈 java 反射机制

    一:Java反射概念 Java反射是Java被视为动态(或准动态)语言的一个关键性质.这个机制允许程序在运行时透过Reflection APIs取得任何一个已知名称的class的内部信息,包括其mod ...

  5. 浅谈java类集框架和数据结构(1)

    在另外一篇博客我简单介绍了java类集框架相关代码和理论. 这一篇博客我主要分析一下各个类集框架的原理以及源码分析. 一:先谈谈LinkedList 这是LinkedList源码的开头,我们能看到几点 ...

  6. 浅谈Java反射

    什么是反射? JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性:这种动态获取信息以及动态调用对象方法的功能称为java语 ...

  7. 浅谈Java反射机制 之 使用类的 属性、方法和构造函数

    前面两篇我们总结了Java反射机制如何获取类的字节码,如何获取构造函数,属性和方法, 这篇我们将进一步验证如何使用我们获取到的属性.方法以及构造函数 1.使用 反射 获取到的 属性 import ja ...

  8. 浅谈Java反射机制 之 获取类的字节码文件 Class.forName("全路径名") 、getClass()、class

    另一个篇:获取 类 的 方法 和 属性(包括构造函数) 先贴上Java反射机制的概念: AVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法: 对于任意一个对象,都能够调用它 ...

  9. 浅谈Java反射机制 之 获取类的 方法 和 属性(包括构造函数)

    上一篇 获取 类 的字节码文件 我们讲到了获取类的字节码文件的三种方法 第三种方法通过getClass("全路径名")获取字节码文件最符合要求 1.获取构造方法 先贴上我们要获取的 ...

随机推荐

  1. [BZOJ1018][SHOI2008]堵塞的交通traffic 时间分治线段树

    题面 介绍一种比较慢的但是好想的做法. 网上漫天的线段树维护联通性,然后想起来费很大周折也很麻烦.我的做法也是要用线段树的,不过用法完全不同. 这个东西叫做时间分治线段树. 首先我们建一个\(1..m ...

  2. mac终端方式修改host

    打开终端 cd /      #进入根目录 ls      #查看根目录下列表,确定有需要打开的目录 cd etc   #进入配置文件目录 ls sudo vim hosts      #用vim打开 ...

  3. 7.使用dom4j实现增删改查

    1.导入dim4j提供的jar包 (1)dom4j,是一个组织,针对xml解析,提供解析器dom4j (2)dom4j不是javase的一部分(jaxp是的) (3)使用dom4j步骤 - 下载并导入 ...

  4. hdu 5964:平行四边形 【计算几何】

    打重现赛时,一点思路也没有,然后又看到这题AC数那么少,就直接放弃了.今天重新看了看,借鉴了下别人的,发现此题应该算是一道可解题. 看上去,这题的ans是同时有两个点作为自变量的函数(然而n^2复杂度 ...

  5. Python基础教程(022)--Pycharm快速体验

    前言 熟悉掌握Python工具 内容 提示 断点调试 目的 学会了解Pycharm的使用 掌握Pycharm执行程序 掌握断点调试模式

  6. NAGIOS(网络监视工具)

    Nagios是一款开源的免费网络监视工具,能有效监控Windows.Linux和Unix的主机状态,交换机,路由器等网络设备,打印机等.在系统或服务状态异常时发出邮件或短信报警第一时间通知网站运维人员 ...

  7. 测开之路四十七:Django之请求静态资源与模板

    框架必要的配置 import sysfrom django.conf.urls import urlfrom django.conf import settingsfrom django.http i ...

  8. spring boot 尚桂谷学习笔记06 异常处理 ---Web

    ------错误处理机制------ 默认效果 1 返回一个默认的错误页面 浏览器发送请求的请求头:优先接收 text/html 数据 客户端则默认响应json数据 : accept 没有说明返回什么 ...

  9. 服务器oracle数据库定时备份

    首先要先建立一个.bat的文件  然后执行这个bat文件 测试是否能得到这个收据库的打包文件. bat文件内容: @echo off@color bdel /f /s /q D:\oracle\bac ...

  10. 2019-4-8 zookeeper集群介绍学习笔记2

    构建高可用ZooKeeper集群原理介绍 ZooKeeper 是 Apache 的一个顶级项目,为分布式应用提供高效.高可用的分布式协调服务,提供了诸如数据发布/订阅.负载均衡.命名服务.分布式协调/ ...