我们先来个示例

用户类

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. Jmeter --Json Extractor (后置处理器)

    一.使用场景 Json Extractor 后置处理器用在返回格式为json的HTTP请求中, 用来获取返回的json中的某个值.并保存成变量供后面的请求进行调用或者断言等. 二.使用方法 1.创建H ...

  2. APPScan安全测试工具

    1.下载IBM Security AppScan Standard.rar免费版,下载地址:https://www.cr173.com/soft/820147.html,安装完成后,配置扫描配置提示无 ...

  3. shell编程程序实例

    1.计算器 #!/bin/bash #test #by authors hdc 2018 function add(){ #实现加法 c=$[ $a + $b ] #相加 echo $c } func ...

  4. 人生苦短_我用Python_javascript_var_function_简单笔记_001

    <!--Javascript_var_001:--> <html> <head> <meta charset="UTF-8"> &l ...

  5. css----overflow(布局)

    CSS overflow 属性用于控制内容溢出元素框时显示的方式. CSS Overflow CSS overflow 属性可以控制内容溢出元素框时在对应的元素区间内添加滚动条. overflow属性 ...

  6. 4412 make menuconfig和make

    一.Menuconfig的操作 • Linux编译器通过.config文件确认哪些代码编译进内核,哪些被裁减掉• menuconfig是生成.config的一个工具• 在Linux发展过程中,配置内核 ...

  7. asp label居中

    https://stackoverflow.com/questions/25245839/align-a-label-to-the-right-using-asp-net Try something ...

  8. Leaflet-Leafletv0.7使用leaflet-bing-layer

    digidem/leaflet-bing-layer: Bing Maps Layer for Leaflet v1.0.0:从标题就可以看出要Leaflet v1.0.0才能用.其实leaflet ...

  9. 小程序报错 Please do not register multiple Pages in undefined.js

    在pages下面建了一个新页面的文件夹,但是没有在page.json里面注册,所以报了这个bug,注册一下就行了.

  10. npm run mock | npm run dev只能启动一个

    解决方法: 开两个命令窗口 先运行npm run mock 再运行npm run dev