反射: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. CSS 外边距合并。

    <div id = "parent"> <div id = "child"> demo </div> </div> ...

  2. android sqlite no such table

    今天在学习android SQLite出现android sqlite no such table错误提示,提示的意思我没有创建我要插入的表,网上也没有搜索一下,也尝试了,发现还是没有解决到我的问题, ...

  3. IDEA安装教程

    1.下载安装程序A,链接:https://pan.baidu.com/s/1IAsGDbApfyNsHuS7_m0rdw 密码:fthp 2.下载一个配置程序B,下载安装之后,暂时不用管,之后会用到. ...

  4. LVM基本应用,扩展及缩减实现!

    LVM概述 [百度百科] LVM是逻辑盘卷管理(LogicalVolumeManager)的简称,它是Linux环境下对磁盘分区进行管理的一种机制,LVM是建立在硬盘和 分区之上的一个逻辑层,来提高磁 ...

  5. C# 插入、删除Excel分页符

    引言 对Excel表格设置分页对我们预览.打印文档时是很方便的,特别是一些包含很多复杂数据的.不规则的表格,为保证打印时每一页的排版美观性或者数据的前后连接的完整性,此时的分页符就发挥了极大的作用.因 ...

  6. SSM-MyBatis-11:Mybatis中查询全部用resultmap

    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 实体类很普通,四个字段,编号,名字,作者名,价格 在接口中的方法声明如下 //查全部 public List& ...

  7. ZooKeeper的使用---Java程序

    一.导入库 以下库存放在目录lib中: audience-annotations-0.5.0.jar jline-0.9.94.jar log4j-1.2.17.jar netty-3.10.6.Fi ...

  8. 1.Spring Framework 5.0 入门篇

    1.为什么学习Spring? 随着对Java EE的不断接触和理解,你会发现Spring  在各个企业和项目中发挥着越来越重要的作用.掌握Spring 已成为我们IT行业生存必学的本领之一. Spri ...

  9. 开源RPC(gRPC/Thrift)框架性能评测

    海量互联网业务系统只能依赖分布式架构来解决,而分布式开发的基石则是RPC:本文主要针对两个开源的RPC框架(gRPC. Apache Thrift),以及配合GoLang.C++两个开发语言进行性能对 ...

  10. 如何深度复制一个javascript对象

    前言 最近有人问我,如何将一个对象复制一份,因为他遇到了一个需求,需要将后端获取的数据,保存一份,原始数据会因为交互而发生变化,最终需要对比两份数据的异同. 他是一个刚入行的小朋友,他的实现方式就是新 ...