反射: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. Python 基础【一】

    python运行流程 一.变量及注释 命名: 合法-变量名由字母.数字和下划线组成,并且不能以数字开头.以下保留字不可以当变量名: ['False', 'None', 'True', 'and', ' ...

  2. 关于HTML、CSS、JavaScript三者关系的简述

    总述 我对于网页这部分的理解吧,对于静态网页来说,无非分为三部分:第一部分.HTML,第二部分.CSS,第三部分.JavaScript(这部分暂且放一边).这俩个给我的第一印象就是,这你妹的都是一串串 ...

  3. Python_struct模块操作二进制文件

    ''' 使用struct模块写入二进制文件 ''' import struct n=130000000 x=96.45 b=True s='a1@中国' sn=struct.pack('if?',n, ...

  4. angular5学习笔记(deep in 路由)

    最近接手了一个angular5的项目.项目本身是由不同的人开发的,所有代码结构风格本身就有很大不同,加上本身接触angular5也不久,之前都是使用1,所有自身压力还是很大的. 接手前几天当然是熟悉代 ...

  5. PAT1129:Recommendation System

    1129. Recommendation System (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue ...

  6. MySql配置优化总结

    当我们被人雇来监测MySQL性能时,人们希望我们能够检视一下MySQL配置然后给出一些提高建议.许多人在事后都非常惊讶,因为我们建议他们仅仅改动几个设置,即使是这里有好几百个配置项.这篇文章的目的在于 ...

  7. 对于spring中事务@Transactional注解的理解

    现在spring的配置都喜欢用注解,这边就说下@Transactional 一.如何开启@Transactional支持 要使用@Transactional,spring的配置文件applicatio ...

  8. linux中查看和开放端口

    装好Tomcat7后,发现除了本机能访问外界访问不了,岂有此理.于是请教百度大神,在费一番周折后,总结步骤如下: 1.修改文件/etc/sysconfig/iptables [root@bogon ~ ...

  9. BufferedInputStream与BufferedOutputStream用法简介

    BufferedInputStream是带缓冲区的输入流,默认缓冲区大小是8M,能够减少访问磁盘的次数,提高文件读取性能:BufferedOutputStream是带缓冲区的输出流,能够提高文件的写入 ...

  10. 使用Spring Boot Actuator、Jolokia和Grafana实现准实时监控

    由于最近在做监控方面的工作,因此也读了不少相关的经验分享.其中有这样一篇文章总结了一些基于Spring Boot的监控方案,因此翻译了一下,希望可以对大家有所帮助. 原文:Near real-time ...