定义

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

用途

在日常的第三方应用开发过程中,经常会遇到某个类的某个成员变量、方法或是属性是私有的或是只对系统应用开放,这时候就可以利用Java的反射机制通过反射来获取所需的私有成员或是方法。当然,也不是所有的都适合反射,之前就遇到一个案例,通过反射得到的结果与预期不符。阅读源码发现,经过层层调用后在最终返回结果的地方对应用的权限进行了校验,对于没有权限的应用返回值是没有意义的缺省值,否则返回实际值起到保护用户的隐私目的。

案例:(重要)

public class Demo1 {
//创建一个自己本身的公共变量
public static demo.knowledgepoints.reflect.Demo1 demo1; private static final boolean flag = true ; //将其私有化,保证不能通过New的方式创建。
private Demo1(){} //创建get方法,用于告知使用者,不能被new,不能被获取。
public static Demo1 getDemo1() throws Exception{
if(flag){
throw new Exception("抱歉,该类不通过new 的方式创建!");
}
return demo1;
} public void print(){
System.out.println("恭喜成功获取Demo1!");
} //通过静态代码块创建实体类。
static {
demo1 = new Demo1();
}
}
public class Demo2 {
//创建一个自己本身的私有变量
private static demo.knowledgepoints.reflect.Demo2 demo2; private static final boolean flag = true ; //将其私有化,保证不能通过New的方式创建。
private Demo2(){} //创建get方法,用于告知使用者,不能被new,不能被获取。
public static Demo2 getDemo2() throws Exception{
if(flag){
throw new Exception("抱歉,该类不通过new 的方式创建!");
}
return demo2;
} public void print(){
System.out.println("恭喜成功获取Demo2!");
} //通过静态代码块创建实体类。
static {
demo2 = new Demo2();
}
}
public class Reflect {
public static void main(String[] args) {
Demo1 demo1 = null;
Demo2 demo2 = null;
try {
//发现new ,编译报错。
//demo1 = new Demo1();
//demo2 = new Demo2(); //发现get方法也获取不到,执行会报异常。
demo1 = Demo1.getDemo1();
demo2 = Demo2.getDemo2();
} catch (Exception e) {
e.printStackTrace();
}
}
}

运行结果:

通过上述代码,我们知道通过普通方法是无法获取到Demo1 和 Demo2。但是看Demo1 和 Demo2的写法,在静态代码块中是new了对象的。说明肯定有办法可以获取到实例。

这里说的方法就是反射。

import java.lang.reflect.Field;

public class Reflect {
public static void main(String[] args) {
Demo1 demo1 = null;
Demo2 demo2 = null;
try {
//首先通过Field,获取需要的类,Field包在jdk的反射包中:java.lang.reflect
Field field1 = Demo1.class.getDeclaredField("demo1");
//获取之后,强制转换成Demo1。
demo1 = (Demo1)field1.get(null);
demo1.print(); //然后我们再来创建一个Demo2.
Field field2 = Demo2.class.getDeclaredField("demo2");
//私有方法需要将:field2.setAccessible(true) ,才能获取到实例类
field2.setAccessible(true);
demo2 = (Demo2)field2.get(null);
demo2.print();
} catch (Exception e) {
e.printStackTrace();
}
}
}

运行结果:

通过上述代码,我们通过反射,获取到Demo1和Demo2的公共属性和私有属性,成功获取到对象。

讲讲反射原理:

通过到class所在目录下,执行javap -c Book.class,可以查看字节码。可以看到一些公共的方法,私有的看不到,不过不影响JVN获取。

下面介绍一下反射的基础类和方法

类名 用途
Class类 代表类的实体,在运行的Java应用程序中表示类和接口
Field类 代表类的成员变量(成员变量也称为类的属性)
Method类 代表类的方法
Constructor类 代表类的构造方法

方法见JDK-API文档。

 
以下是常见方法的使用案例:
package demo.knowledgepoints.reflect;

public class Book {
private final static String TAG = "BookTag"; private String name;
private String author; @Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", author='" + author + '\'' +
'}';
} public Book() {
} private Book(String name, String author) {
this.name = name;
this.author = author;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getAuthor() {
return author;
} public void setAuthor(String author) {
this.author = author;
} private String declaredMethod(int index) {
String string = null;
switch (index) {
case 0:
string = "I am declaredMethod 1 !";
break;
case 1:
string = "I am declaredMethod 2 !";
break;
default:
string = "I am declaredMethod 1 !";
} return string;
}
}
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method; public class Reflect {
public static void main(String[] args) {
reflectNewInstance();
reflectPrivateConstructor();
reflectPrivateField();
reflectPrivateMethod();
} /**
* 通过反射获取对象
*/
public static void reflectNewInstance() {
try {
Class<?> classBook = Class.forName("demo.knowledgepoints.reflect.Book");
Object objectBook = classBook.newInstance();
Book book = (Book) objectBook;
book.setName("Java进阶之光");
book.setAuthor("蕾蕾");
System.out.println("reflectNewInstance book = " + book.toString());
} catch (Exception ex) {
ex.printStackTrace();
}
} // 反射私有的构造方法
public static void reflectPrivateConstructor() {
try {
Class<?> classBook = Class.forName("demo.knowledgepoints.reflect.Book");
Constructor<?> declaredConstructorBook = classBook.getDeclaredConstructor(String.class,String.class);
declaredConstructorBook.setAccessible(true);
Object objectBook = declaredConstructorBook.newInstance("Java开发艺术探索","磊磊");
Book book = (Book) objectBook;
System.out.println("reflectPrivateConstructor book = " + book.toString());
} catch (Exception ex) {
ex.printStackTrace();
}
} // 反射私有属性
public static void reflectPrivateField() {
try {
Class<?> classBook = Class.forName("demo.knowledgepoints.reflect.Book");
Object objectBook = classBook.newInstance();
Field fieldTag = classBook.getDeclaredField("TAG");
fieldTag.setAccessible(true);
String tag = (String) fieldTag.get(objectBook);
System.out.println("reflectPrivateField tag = " + tag);
} catch (Exception ex) {
ex.printStackTrace();
}
} // 反射私有方法
public static void reflectPrivateMethod() {
try {
Class<?> classBook = Class.forName("demo.knowledgepoints.reflect.Book");
Method methodBook = classBook.getDeclaredMethod("declaredMethod",int.class);
methodBook.setAccessible(true);
Object objectBook = classBook.newInstance();
String string = (String) methodBook.invoke(objectBook,1); System.out.println("reflectPrivateMethod string = " + string);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}

运行结果:

参考:https://www.jianshu.com/p/9be58ee20dee

《Java基础知识》Java 反射详解的更多相关文章

  1. Java基础13:反射详解

    本节主要介绍Java反射的原理,使用方法以及相关的技术细节,并且介绍了关于Class类,注解等内容. 具体代码在我的GitHub中可以找到 https://github.com/h2pl/MyTech ...

  2. Java基础-面向接口编程-JDBC详解

    Java基础-面向接口编程-JDBC详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.JDBC概念和数据库驱动程序 JDBC(Java Data Base Connectiv ...

  3. java基础(3)--详解String

    java基础(3)--详解String 其实与八大基本数据类型一样,String也是我们日常中使用非常频繁的对象,但知其然更要知其所以然,现在就去阅读源码深入了解一下String类对象,并解决一些我由 ...

  4. Linux基础知识之挂载详解(mount,umount及开机自动挂载)

    Linux基础知识之挂载详解(mount,umount及开机自动挂载) 转载自:http://www.linuxidc.com/Linux/2016-08/134666.htm 挂载概念简述: 根文件 ...

  5. 学习Spring必学的Java基础知识(1)----反射(转)

    引述要学习Spring框架的技术内幕,必须事先掌握一些基本的Java知识,正所谓"登高必自卑,涉远必自迩".以下几项Java知识和Spring框架息息相关,不可不学(我将通过一个系 ...

  6. 学习Spring必学的Java基础知识(1)----反射

    引述要学习Spring框架的技术内幕,必须事先掌握一些基本的Java知识,正所谓"登高必自卑,涉远必自迩".以下几项Java知识和Spring框架息息相关,不可不学(我将通过一个系 ...

  7. JAVA基础知识|java虚拟机(JVM)

    一.JVM简介 java语言是跨平台的,兼容各种操作系统.实现跨平台的基石就是虚拟机(JVM),虚拟机不是跨平台的,所以不同的操作系统需要安装不同的jdk版本(jre=jvm+类库:jdk=jre+开 ...

  8. [java基础知识]java安装步骤

    jre:  java运行环境.  jre =  java虚拟机 + 核心类库(辅助java虚拟机运行的文件).如果只是运行java程序,只需要安装jre.    jdk: java开发工具集   jd ...

  9. java基础知识——Java的定义,特点和技术平台

    (作者声明:对于Java编程语言,很多人只知道怎么用,却对其了解甚少.我也是其中一员.所以菜鸟的我,去查询了教科书以及大神的总结,主要参考了<Java核心技术>这本神作.现在分享给大家!) ...

  10. 计算机基础知识和tcp详解

    计算机基础知识 作为应用软件开发程序员是写应用软件的,而应用软件必须应用在操作系统之上,调用操作系统接口,由操作系统控制硬件 比如客户端软件想要基于网络发送一条消息给服务端软件,流程是: 1.客户端软 ...

随机推荐

  1. windows 10安装和配置caffe教程 | Install and Configure Caffe on windows 10

    本文首发于个人博客https://kezunlin.me/post/1739694c/,欢迎阅读! Install and Configure Caffe on windows 10 Part 1: ...

  2. 基于 HTML5 WebGL 和 VR 技术的 3D 机房数据中心可视化

    前言 在 3D 机房数据中心可视化应用中,随着视频监控联网系统的不断普及和发展, 网络摄像机更多的应用于监控系统中,尤其是高清时代的来临,更加快了网络摄像机的发展和应用. 在监控摄像机数量的不断庞大的 ...

  3. Tomcat安装和使用

    1.Tomcat简介 Tomcat是Apache开源组织下的开源免费的中小型Web应用服务器,支持javaEE中的servlet和jsp规范. 2.Windows版安装和使用 下载地址:http:// ...

  4. 学习Python第一天:找了4本专属小白的书籍(前期入门打基础)

    我们提供一个初学者最好的Python书籍列表.Python是一个初级程序员可以学习编程的最友好语言之一.为了帮助您开始使用Python编程,我们分享此列表.泡一杯茶,选一本书阅读,开始使用Python ...

  5. spark graphX作图计算

    一.使用graph做好友推荐 import org.apache.spark.graphx.{Edge, Graph, VertexId} import org.apache.spark.rdd.RD ...

  6. Mybatis拦截器实现原理深度分析

    1.拦截器简介 拦截器可以说使我们平时开发经常用到的技术了,Spring AOP.Mybatis自定义插件原理都是基于拦截器实现的,而拦截器又是以动态代理为基础实现的,每个框架对拦截器的实现不完全相同 ...

  7. Android PhotoView基本功能实现

    Android开发过程中,想必都使用过PhotoView来实现图片展示的功能.在最新版的sdk(android-23)有了一个原生的photoView,并且代码实现也很简单,逻辑也很清晰.我们在实际的 ...

  8. python logging模块小记

    1.简单的将日志打印到屏幕 import logging logging.debug('This is debug message') logging.info('This is info messa ...

  9. auto_modify_ip Shell脚本安装

    #!/bin/bash # : #This author is DKS #auto modify ip of linux ############################### IP_NAME ...

  10. java 实现文件读写操作

    import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; /* JAVA IO 读写操作 20 ...