说到反射机制,第一次接触的人可能会比较懵,反射?什么反射?怎么反射?反射是干嘛的?下面我将在这篇文章中讲讲Java的反射机制


不过在这之前,还有一个问题需要解决,标题名中的动态性,说起动态性,我先介绍介绍动态语言和静态语言

静态语言

  静态语言是在编译时变量的数据类型即可确定的语言,多数静态类型语言要求在使用变量之前必须声明数据类型。 例如:C++、Java、Delphi、C#等。

动态语言

  动态语言是在运行时确定数据类型的语言。变量使用之前不需要类型声明,通常变量的类型是被赋值的那个值的类型。 例如PHP/ASP/Ruby/Python/Perl/ABAP/SQL/JavaScript/Unix Shell等等。并且动态语言,是指程序在运行时可以改变其结构:新的函数可以引进,已有的函数可以被删除等结构上的变化。

  这时可能你就会有疑问了,既然Java属于静态语言,又怎么会有动态性?其一就是Java存在与动态性相关的机制:反射机制。Java通过反射机制,可以在程序运行时加载,探知和使用编译期间完全未知的类,并且可以生成相关类对象实例,从而可以调用其方法或则改变某个属性值。所以JAVA也可以算得上是一个半动态的语言


下面来讲讲反射机制

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

  反射的原理在于Class对象

    看一看程序加载的过程

从图中大概可以看出反射是干什么用的了,那接下来就讲讲有关反射的其他方面

  反射的API

    反射API用来生成JVM中的类、接口或则对象的信息。
    - Class类:反射的核心类,可以获取类的属性,方法等信息。
    - Field类:Java.lang.reflec包中的类,表示类的成员变量,可以用来获取和设置类之中的属性值。
    - Method类: Java.lang.reflec包中的类,表示类的方法,它可以用来获取类中的方法信息或者执行方法。
    - Constructor类: Java.lang.reflec包中的类,表示类的构造方法。


下面就来讲讲怎么使用反射了  

1.步骤

  • 获取想要操作的类的Class对象
  • 调用Class类中的方法
  • 使用反射API来操作这些信息

2.获取Class对象的方法

//假设我们有一个Student类
方法一、(推荐)
Class clas = Class.forName("first.Student");//“”里写的是类的全路径 方法二、
Student stu = new Student();
Class clas = stu.getClass(); 方法三、
Class clas = Student.Class;

可以试试用两个不同的方法获取clas1和clas2,然后System.ou.println(clas1==clas2)看看会输出什么,原因在图上

3.获取构造方法、字段、main方法并调用

Student.java

public class Student {
public String name;
protected int age;
char sex;
private String phoneNum; public static void main(String[] args) { System.out.println("main方法执行了。。。"); }
//---------------构造方法-------------------
Student(String str) {
System.out.println("(默认)的构造方法 s = " + str);
} // 无参构造方法
public Student() {
System.out.println("调用了公有、无参构造方法执行了。。。");
} // 有一个参数的构造方法
public Student(char name) { System.out.println("姓名:" + name);
} // 有多个参数的构造方法
public Student(String name, int age) {
this.name=name;this.age=age;
System.out.println("姓名:" + name + "年龄:" + age);// 这的执行效率有问题,以后解决。
} // 受保护的构造方法
protected Student(boolean n) {
System.out.println("受保护的构造方法 n = " + n);
} // 私有构造方法
private Student(int age) {
System.out.println("私有的构造方法 年龄:" + age);
} public String toString() {
return "Student [name=" + name + ", age=" + age + ", sex=" + sex
+ ", phoneNum=" + phoneNum + "]";
}
}

Constructors.java(构造方法)

package first;

import java.lang.reflect.Constructor;

public class Constructors {
public static void main(String[] args) throws Exception { Class clas=Class.forName("first.Student"); System.out.println("所有公有构造方法");
Constructor[] conArry=clas.getConstructors();
for(int i=;i<conArry.length;i++) {
System.out.println(conArry[i]);
} System.out.println("所有的构造方法");
conArry=clas.getDeclaredConstructors();
for(int i=;i<conArry.length;i++) {
System.out.println(conArry[i]);
} System.out.println("获取公有无参的构造方法");
Constructor con=clas.getConstructor(null);
System.out.println("con="+con);
Object obj=con.newInstance(); System.out.println("获取私有构造方法,并调用");
con=clas.getDeclaredConstructor(char.class);
System.out.println(con);
//con.setAccessible(true);//暴力访问,针对private方法和字段时使用
obj=con.newInstance('a');//创建对象
}
}

输出

所有公有构造方法
public first.Student(char)
public first.Student()
public first.Student(java.lang.String,int)
所有的构造方法
protected first.Student(boolean)
private first.Student(int)
public first.Student(char)
public first.Student()
first.Student(java.lang.String)
public first.Student(java.lang.String,int)
获取公有无参的构造方法
con=public first.Student()
调用了公有、无参构造方法执行了。。。
获取私有构造方法,并调用
public first.Student(char)
姓名:a

Fields.java(字段)

package first;

import java.lang.reflect.Field;

public class Fields {

    public static void main(String[] args)throws Exception {
// TODO Auto-generated method stub
Class StuClass=Class.forName("first.Student"); System.out.println("获取所有公有的字段");
Field[] fieldArry=StuClass.getFields();
for(Field f:fieldArry) {
System.out.println(f);
}
System.out.println("获取所有的字段(包括私有、受保护、默认的)");
fieldArry=StuClass.getDeclaredFields();
for(Field f:fieldArry) {
System.out.println(f);
}
System.out.println("获取公有字段并调用");
Field f = StuClass.getField("name");
System.out.println(f);
Object obj=StuClass.getConstructor().newInstance();
StuClass.getConstructor(String.class,int.class).newInstance("a",);
f.set(obj, "b");
Student stu=(Student)obj;
System.out.println(stu.name); System.out.println("获取私有字段并调用");
f = StuClass.getDeclaredField("phoneNum");
System.out.println(f);
f.setAccessible(true);//暴力反射,解除私有限定
f.set(obj, "");
System.out.println("验证电话:" + stu);
} }

输出

获取所有公有的字段
public java.lang.String first.Student.name
获取所有的字段(包括私有、受保护、默认的)
public java.lang.String first.Student.name
protected int first.Student.age
char first.Student.sex
private java.lang.String first.Student.phoneNum
获取公有字段并调用
public java.lang.String first.Student.name
调用了公有、无参构造方法执行了。。。
姓名:a年龄:
b
获取私有字段并调用
private java.lang.String first.Student.phoneNum
验证电话:Student [name=b, age=, sex=

Main.java

package first;

import java.lang.reflect.Method;

public class Main {
public static void main(String[] args) {
try {
// 1、获取Student对象的字节码
Class clazz = Class.forName("first.Student"); // 2、获取main方法 Method methodMain = clazz.getMethod("main", String[].class);// 第一个参数:方法名称,第二个参数:方法形参的类型, // 3、调用main方法
// methodMain.invoke(null, new String[]{"a","b","c"});
// 第一个参数,对象类型,因为方法是static静态的,所以为null可以,第二个参数是String数组
// 这里拆的时候将 new String[]{"a","b","c"} 拆成3个对象。。。所以需要将它强转。
methodMain.invoke(null, (Object) new String[] {});// 方式一
// methodMain.invoke(null, new Object[]{new String[]{"a","b","c"}});//方式二
} catch (Exception e) {
e.printStackTrace();
}
}
}

未完待续。。。。。

参考文章:

https://blog.csdn.net/sinat_38259539/article/details/71799078

Java动态性之反射机制(reflection)的更多相关文章

  1. Java动态性之--反射机制

    1. 动态语言 程序运行时,可以改变结构或变量类型.典型的语言: Python.ruby.javascript等 如下javascript代码 function test(){ var s = &qu ...

  2. Java中的反射机制Reflection

    目录 什么是反射? 获取.class字节码文件对象 获取该.class字节码文件对象的详细信息 通过反射机制执行函数 反射链 反射机制是java的一个非常重要的机制,一些著名的应用框架都使用了此机制, ...

  3. Java - 反射机制(Reflection)

    Java - 反射机制(Reflection)     > Reflection 是被视为 动态语言的关键,反射机制允许程序在执行期借助于 Reflection API 取得任何类的       ...

  4. 小白都能学会的Java注解与反射机制

    前言 Java注解和反射是很基础的Java知识了,为何还要讲它呢?因为我在面试应聘者的过程中,发现不少面试者很少使用过注解和反射,甚至有人只能说出@Override这一个注解.我建议大家还是尽量能在开 ...

  5. 浅说Java中的反射机制(一)

    在学习传智播客李勇老师的JDBC系列时,会出现反射的概念,由于又是第一次见,不免感到陌生.所以再次在博客园找到一篇文章,先记录如下: 引用自java中的反射机制,作者bingoideas.(()为我手 ...

  6. java学习之反射机制

    java语言区别于C,C++等准静态语言的最大特点就是java的反射机制.静态语言的最直接定义就是不能在运行时改变程序结构或变量的类型.按照这样的定义,python,ruby是动态语言,C,C++,J ...

  7. Java中的反射机制(一)

    基本概念 在Java运行时环境中,对于任意一个类,能否知道这个类有哪些属性和方法?对于任意一个对象,能否调用它的任意一个方法? 答案是肯定的. 这种动态获取类的信息以及动态调用对象的方法的功能来自于J ...

  8. java 中利用反射机制获取和设置实体类的属性值

    摘要: 在java编程中,我们经常不知道传入自己方法中的实体类中到底有哪些方法,或者,我们需要根据用户传入的不同的属性来给对象设置不同的属性值,那么,java自带的反射机制可以很方便的达到这种目的,同 ...

  9. java中的反射机制在Android开发中的用处

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

随机推荐

  1. pi的求法 acos(-1.0)

    pi=acos(-1.0) https://www.luogu.org/problemnew/show/T4529 #include <cstdio> #include <cstdl ...

  2. ssm框架中Controller层的junit测试_我改

    Controller测试和一般其他层的junit测试可以共用一个BaseTest 一.BaseTest如下: @RunWith(SpringJUnit4ClassRunner.class) @WebA ...

  3. Solr记录-solr文档xml

    Solr添加文档(XML) 在上一章中,我们学习解释了如何向Solr中添加JSON和.CSV文件格式的数据.在本章中,将演示如何使用XML文档格式在Apache Solr索引中添加数据. 示例数据 假 ...

  4. jQuery 实现 bootstrap 模态框 删除确认

    思路: 点击删除按钮,通过jquery将删除操作的URL赋值到页面URL元素,并弹出会话框 用户点击确认,通过jquery获取URL,并发送删除请求至后台. 一.删除button <a clas ...

  5. Redis五种数据结构(Windows Server)

    1.Redis的五种数据结构 这里推荐大家在命名redis的key的时候最好的加上前缀,并且使用 :来分割前缀 ,这里在使用可视化工具查看的时候就比较好区分,比如我的的前缀是 Demo:test:(一 ...

  6. 前三章 man手册 查看文件

    1 – 3章 1.1 man手册: 分1 - 9个区域,可以认为是一个一个小节 把man手册理解为一本书 第一节:可执行程序或shell命令 第二节:系统调用 第三节:库调用 第四节:特殊文件 第五节 ...

  7. 爬虫笔记之刷小怪练级:yymp3爬虫(音乐类爬虫)

    一.目标 爬取http://www.yymp3.com网站歌曲相关信息,包括歌曲名字.作者相关信息.歌曲的音频数据.歌曲的歌词数据. 二.分析 2.1 歌曲信息.歌曲音频数据下载地址的获取 随便打开一 ...

  8. 利用itertools生成密码字典,多线程撞库破解rar压缩文件密码

    脚本功能: 利用itertools生成密码字典(迭代器形式) 多线程并发从密码字典中取出密码进行验证 验证成功后把密码写入文件中保存 #!/usr/bin/env python # -*- codin ...

  9. js星星评分插件

    下载:https://files.cnblogs.com/files/wordblog/%E6%98%9F%E6%98%9F%E6%8F%92%E4%BB%B6.rar

  10. mysql集成部署

    经常听说mysql数据库是集成在系统中,也一直不太明白集成的概念.今天才明白集成的概念就是将mysql所有的文件放到一个文件夹下放到系统中,也就是将mysql采用目录迁移部署的方式进行安装.在上一篇研 ...