反射:reflect   成员属性:Field  成员方法:Method 构造方法:Constructor  类:Class

引用,援引:invoke   新实例:newInstance  Declared:公开

什么是反射?

反射是一种机制,利用该机制可以在程序运行过程中对类进行解剖并操作类中的方法,属性,构造方法等成员

是一种通过class文件对类中所有成员属性,构造方法,成员方法进行操作的方式,无论是什么权限都可以进行操作

什么是Class对象?

学习反射主要是操作Class对象,那么什么是Class对象?

Class 类的实例表示正在运行的 Java 应用程序中的类和接口。枚举是一种类,注释是一种接口。每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也表示为 Class 对象。

Class 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的。

class文件和Class是两个概念

也就是说,Class也是java语言中的一个类,程序运行时,会将class文件加载到内存并对该类进行解剖,解剖类时会获得很多的数据,有成员变量数据,成员方法数据,构造方法数据等,JVM为了方便管理这些类的数据,内部会为每一个加载到内存的class文件创建一个Class对象,这个Class对象目的就是用来封装解剖得到的所有该类的数据

操作Class对象即可获取对应类的数据

创建对象的五种方式:

  1. 直接new对象

String str=new String(“张三”);

  1. 如果类中有无参构造方法,可以使用该类对应的Class文件直接创建对象(反射)

Student s=Student.class.newInstance();

  1. 通过类的Class对象获取该类的构造方法,通过构造方法创建对象(反射)

Class s1=Student.class;

Constructor c1=c1.getConstructor();

Student s2=c1.newInstance();

  1. 通过反序列化获取对象
  2. 通过Clone….获取对象(了解)

反射有什么用,有什么应用的地方?

  1. 一种新的创建对象,操作对象的方式
  2. 可以降低程序的耦合度,降低程序的维护难度

举例说明:

通过反射比较常用的获取类对象的方式:

Class class=Class.forName(“包名.类名”);

通过类的全限命名(字符串类型)即可创建对象,可以将该字符串以键值对的形式存储到properties文件中,

如果类名改变,只需要修改properties配置文件即可

而通过new出来的对象,如果类名发生改变,则需要修改代码

  1. ssh(Spring,Struts,Hibernate)框架底层就使用了大量的反射

反射怎么使用?

先总结一下,通过反射可以获取类的构造方法(Constructor),成员属性(Field),成员方法(Method),针对操作公有数据和操作所有权限数据分开来说

操作公有数据:

获取构造方法:如果构造函数有参数在参数列表加上相应参数类型的class属性即可

Constructor getConstructor()

Constructor[] getConstructors()

获取成员属性:需要传入属性名称

Field getField(String name);

Field[] getFields();

获取成员方法:(通过方法名称和参数才能唯一标识一个方法,所以需要传入方法名称和参数)

Method getMethod(String methodName,参数…)

Method[] getMethods()

操作所有权限的数据

在操作公有数据基础上,get后面加上Declared,如果操作构造方法或者成员属性或者成员方法,先用方法对象或者属性对象调用setAccessible并且传入true即可

代码详解:

  

package com.ahd.lianxi;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; public class Demo01 {
public static void main(String[] args) throws Exception {
//练习反射 /*
* 获取Class对象的三种方式
* 方式一:通过对象调用getClass方法获取
*
* 方式二:通过类名的class属相获取
*
* 方式三:通过类的权限命名加载Class文件,需要抛出异常(这种方法比较常用)
* */
Student s=new Student("zhangsan");
Class<? extends Student> c1 = s.getClass(); Class<Student> c2 = Student.class; Class.forName("com.ahd.lianxi.Student"); /*
* 获取Class对象,可以通过该对象获取该对象相应的构造方法,成员属性
* ,成员方法,进而进行操作
* 首先说操作构造方法,创建对象
* Constructor<? extends Student> constructorC1 = c1.getConstructor();
* 该构造方法获取公有的构造方法,传入相应的参数表示获取对应的构造方法,
* Constructor<? extends Student> declaredConstructorC1 = c1.getDeclaredConstructor();
* 该构造方法获取所有权限的构造方法,传入相应的参数表示获取对应的构造方法,比较常用
* Constructor<?>[] constructors = c1.getConstructors();
* 该构造方法获取所有公有的构造方法,比较常用
* Constructor<?>[] declaredConstructors = c1.getDeclaredConstructors();
* 该构造方法获取所有权限的构造方法,
*
* 如果要通过无参构造方法创建对象,可以直接使用Class对象的newInstance方法获取相应对象
* Student student1 = c1.newInstance();
* */
Constructor<? extends Student> constructorC1 = c1.getConstructor();
Constructor<? extends Student> constructorC2 = c1.getConstructor(String.class);
Constructor<? extends Student> declaredConstructorC1 = c1.getDeclaredConstructor(); Constructor<?>[] constructors = c1.getConstructors();
Constructor<?>[] declaredConstructors = c1.getDeclaredConstructors();
//通过Declared获取的属性,方法..,需要先通过属性对象或者方法对象暴力破解一下
//declaredConstructorC1.setAccessible(true);
declaredConstructorC1.setAccessible(true);
//通过迭代器可以遍历所有构造方法,进行相应操作
//略... //使用构造方法创建对象
Student student = constructorC1.newInstance();
Student student2 = constructorC2.newInstance("赵四"); /*
* 通过Class对象获取成员属性
* Field field1 = c1.getField("username");
* 获取公有的指定属性名称的属性对象
* Field field2 = c1.getDeclaredField("username");
* 获取所有权限的指定属性名称的属性对象
* Field[] fields = c1.getFields();
* 获取公有的所有属性对象
* Field[] declaredFields = c1.getDeclaredFields();
* 获取所有权限的所有属性对象
* */
Field field1 = c1.getField("username");
Field field2 = c1.getDeclaredField("username");
//通过Declared获取的属性,方法..,需要先通过属性对象或者方法对象暴力破解一下
//field2.setAccessible(true);
field2.setAccessible(true); /*
* 对属性进行操作
* get方法获取属性的值: Object get(Object obj)
* 返回指定对象上此 Field 表示的字段的值。
* set方法为属性赋值:void set(Object obj, Object value)
* 将指定对象变量上此 Field 对象表示的字段设置为指定的新值。
* 个人理解:obj即该成员属性所属于的对象,value为为该属性赋的值
* */
field1.set(student,"lisi");
System.out.println(field1.get(student)); Field[] fields = c1.getFields();
Field[] declaredFields = c1.getDeclaredFields(); //通过迭代器可以遍历所有属性,进行相应操作
//略... /*
* 通过Class对象获取成员方法,获取成员方法需要传入方法名称和参数类型(类型是对应的class文件)
* ,方法获取后可以指定对象调用成员方法
* ,调用成员方法需要指定对象和参数列表(可变参数)
* public Method getMethod(String name,
* Class<?>... parameterTypes)
* 获取公有的成员方法
* Method declaredMethod = c1.getDeclaredMethod("getUsername");
* 获取所有权限的一个成员方法
* Method[] methods = c1.getMethods();
* 获取所有公有的成员方法
* Method[] declaredMethods = c1.getDeclaredMethods();
* 获取所有具有所有权限的成员方法
*
*
* */
Method method = c1.getMethod("getUsername");//调用无参方法,参数可以不写
Method declaredMethod = c1.getDeclaredMethod("getUsername");
//通过Declared获取的属性,方法..,需要先通过属性对象或者方法对象暴力破解一下
//declaredMethod.setAccessible(true);
declaredMethod.setAccessible(true); Method[] methods = c1.getMethods();
Method[] declaredMethods = c1.getDeclaredMethods(); System.out.println("##########################");
//方法调用
method.invoke(student);
System.out.println(method.invoke(student)); }
}

我有一句话想要对你说

地基越牢固,楼才能建的更高

笔者原创,欢迎大佬指出错误

java_反射的更多相关文章

  1. java_反射_及其简单应用(2016-11-16)

    话不多说直接上代码 接口: package bean; /** * user接口 */ public interface User { public String getName(); public ...

  2. Java_反射demo

    package com.cnit.reflect; import java.lang.reflect.Field; import java.lang.reflect.Method; public cl ...

  3. Java_反射_范型

    虽然从来没有被面过,但是必须知道,因为classForname classloader被面过多次了. 一.Class.forName动态加载  1.编译时加载类是静态加载类,             ...

  4. Java_反射机制详解

    本篇文章依旧采用小例子来说明,因为我始终觉的,案例驱动是最好的,要不然只看理论的话,看了也不懂,不过建议大家在看完文章之后,在回过头去看看理论,会有更好的理解. 下面开始正文. [案例1]通过一个对象 ...

  5. JAVA全套资料含视频源码(持续更新~)

    本文旨在免费分享我所搜集到的Java学习资源,所有资源都是通过正规渠道获取,不存在侵权.现在整理分享给有所需要的人. 希望对你们有所帮助!有新增资源我会更新的~大家有好的资源也希望分享,大家互帮互助共 ...

  6. Java_通过反射调用类中的方法

    先上一个基本的封装: /** * 获取classType * * @param type * @param provinceCode * @param cityCode * @return * @th ...

  7. java_ _反射

    Java语言的反射机制初步学习 首先看下基本概念: (一)在Java运行时环境中,对于任意一个类,能否知道这个类有哪些属性和方法?对于任意一个对象,能否调用它的任意一个方法?答案是肯定的.这种动态获取 ...

  8. JAVA_基础反射机制

    Java反射机制概述 Reflection(反射)是被视为动态语言的关键,反射机制允许程序在执行期 借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内 部属性及方法. 加 ...

  9. JAVA_基础反射创建运行时类的对象

    通过反射去创建对应的运行时类的对象 newInstance():调用此方法,创建对应的运行时类的对象.内部调用的是空参的构造器. 要想此方法正常的创建运行时类的对象,要求: 1.运行时类必须提供空参构 ...

随机推荐

  1. 航遇项目react踩坑

    1.iconfont应用: a.正常用法如下 <span className='iconfont' > iconfont的代码,例如: </span> b.react不能动态 ...

  2. C Primer Plus 第6章 C控制语句:循环 编程练习

    记录下写的最后几题. 14. #include <stdio.h> int main() { double value[8]; double value2[8]; int index; f ...

  3. GPU渲染流水线的简单概括

    GPU流水线 主要分为两个阶段:几何阶段和光栅化阶段   几何阶段      顶点着色器 --> 曲面细分着色器(可选)----->几何着色器(可选)----->裁剪-->屏幕 ...

  4. Spring Cloud Sleuth服务链路追踪(zipkin)(转)

    这篇文章主要讲述服务追踪组件zipkin,Spring Cloud Sleuth集成了zipkin组件. 一.简介 Spring Cloud Sleuth 主要功能就是在分布式系统中提供追踪解决方案, ...

  5. Scrapy 1.4 文档 01 初窥 Scrapy

    初窥 Scrapy Scrapy 是用于抓取网站并提取结构化数据的应用程序框架,其应用非常广泛,如数据挖掘,信息处理或历史存档. 尽管 Scrapy 最初设计用于网络数据采集(web scraping ...

  6. windows 搭建 IBM Hyperledger Fabric(超级账本)开发环境

    一.概述 Hyperledge fabric项目是IBM开源的区块链项目.Github地址:https://github.com/hyperledger/fabric 想对fabric有具体的认识,可 ...

  7. IDEA破解 Intellij IDEA license server 激活(可用)

    激活地址如下图所示: 2018 intellij idea 注册码(亲测可用): C0FHYYCJ22-eyJsaWNlbnNlSWQiOiJDMEZIWVlDSjIyIiwibGljZW5zZWVO ...

  8. Python爬取谷歌街景图片

    最近有个需求是要爬取街景图片,国内厂商百度高德和腾讯地图都没有开放接口,查询资料得知谷歌地图开放街景api 谷歌捷径申请key地址:https://developers.google.com/maps ...

  9. engine.go

    package ;;;;;;;;) ;;;;;) ) ) ) ;; ;;, types.DocumentIndexData{}, true)     for {         runtime.Gos ...

  10. 【强连通分量】Bzoj1051 HAOI2006 受欢迎的牛

    Description 每一头牛的愿望就是变成一头最受欢迎的牛.现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎. 这种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认 ...