java中的反射应用实现

反射

我们先创建一个Student类出来。注意类中的成员变量、构造方法、成员方法公共还是私有

package com.reflect;

public class Student {
 //成员变量
 public String name;//公共
 private int age;//私有

 //构造方法
 public Student() {
 super();
 // TODO Auto-generated constructor stub
 }

 //私有构造方法
 private Student(String name) {
 this.name = name;
 }

 public Student(String name, int age) {
 super();
 this.name = name;
 this.age = age;
 }

 //成员方法(getXxx/setXxx)
 public String getName() {
 return name;
 }

 public void setName(String name) {
 this.name = name;
 }

 public int getAge() {
 return age;
 }

 public void setAge(int age) {
 this.age = age;
 }

 //成员方法
 public void study() {
 System.out.println("我爱学习java!");
 }
 // 私有
 private void study(String string) {
 System.out.println("我还爱学习"+string);
 }
 @Override
 public String toString() {
 return "Student [name=" + name + ", age=" + age + "]";
 }
}

反射概述

1、反射:反射是通过class文件对象,去使用文件对象的成员方法、构造方法、成员变量

回想之前我们使用对象方法时必须通过new对象去使用。new Student().study(),此时我们就发现了一个问题,小例中我们肯定是知道Student类中是有study()方法的,如果我们想使用用这个类但却不清楚类中的信息,此时反射就起到了一定作用。

其实反射的作用,不止这一点点。如下

2、反射可以提高程序的灵活性和扩展性,降低耦合性,提高自适应能力。它允许程序创建和控制任何类的对象,无需提高硬编码目标类

Java反射技术应用领域很广,后期如软件测试、JavaBean等都有很重要的作用

许多流行的开源框架例如Struts、Hibernate、Spring在实现过程中都采用了该技术

3、性能问题:使用反射基本上是一种解释操作,用于字段和方法接入时要远慢于直接代码。因此Java反射机制只要应用在对;灵活性和扩展性要求很高的系统框架上,普通程序不建议使用使用反射会模糊程序内部逻辑:程序员希望在代码中看到程序的逻辑,反射等绕过了源代码的技术,因而会带来维护问题。

反射获取Class类对象

  1. 要想使用反射,我们必须得到class文件对象,也就是我们要使用的类Class对象
  2. 三种获得class文件对象的方法:
    1. Object类的getClass()方法
    2. 数据类型的静态属性class
    3. Class类中的静态方法public static Class forName(String classname)

一般我们使用第三种

package com.reflect;

public class Demo {
 public static void main(String[] args) throws ClassNotFoundException {
 // 方式1
 Student p = new Student();
 Class c = p.getClass();

 Student p2 = new Student();
 Class c2 = p2.getClass();

 System.out.println(p == p2);// false不是同一Student对象
 System.out.println(c == c2);// true是同一class对象

 // 方式2
 Class c3 = Student.class;
 System.out.println(c == c3);//true是同一class对象

 // 方式3
 // ClassNotFoundException(类找不到时)
 Class c4 = Class.forName("com.reflect.Student");
 System.out.println(c == c4);//true是同一class对象
 }

}

Class类中相关的几个类

  • 和成员变量有关 Field
  • 和构造方法有关 Constructor
  • 和成员方法有关 Method
  • 有关的几个方法
  • public T newInstance(Object… initargs) 使用此 Constructor 对象表示的构造方法来创建该构造方法的声明类的新实例,并用指定的初始化参数初始化该实例。

反射获取构造方法

先来认识几个方法

public Constructor getConstructor()// 公共构造方法对象
public Constructor[] getConstructors()//所有公共构造方法对象
public Constructor[] getDeclaredConstructors()//所有构造方法对象
public Constructor getDeclaredConstructor()//获取私有构造方法对象
public Constructor<T> getConstructor(Class<?>... parameterTypes)// 参数表示的是:你要获取的构造方法的构造参数个数及数据类型的class字节码文件对象
public void setAccessible(boolean flag)// 值为true则指示反射的对象在使用时应该取消Java语言访问检查。 暴力访问
package com.reflect;

import java.lang.reflect.Constructor;

public class ConstructorDemo {
 public static void main(String[] args) throws Exception {
 // 获取字节码文件对象
 Class c = Class.forName("com.reflect.Student");

 // 获取所有构造方法
 Constructor[] cons = c.getDeclaredConstructors();
 for (Constructor con : cons) {
  System.out.println(con);
 }

 // 获取单个构造方法
 Constructor con = c.getConstructor();// 返回的是构造方法对象
 Constructor con1 = c.getConstructor(String.class, int.class);// 返回的是有参构造方法对象
 Constructor con2 = c.getDeclaredConstructor(String.class);
 //创建对象
 Object obj = con.newInstance();
 Object obj1=con1.newInstance("小米",12);
 // 暴力访问
 con2.setAccessible(true);// 值为true则指示反射的对象在使用时应该取消Java语言访问检查。
 Object obj2 = con2.newInstance("小白");

 System.out.println(obj.toString());
 System.out.println(obj1.toString());
 System.out.println(obj2.toString());

 }
}

运行结果:

反射获取成员变量

**类比上面Constructor类中的方法,这个类也有同样的方法,获取所有成员变量(返回数组),获取私有成员变量等 这里不再赘述 **

package com.reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;

/*
 * 通过发生获取成员变量并使用
 */
public class FieldDemo {
 public static void main(String[] args) throws Exception {
 // 获取字节码文件对象
 Class c = Class.forName("com.reflect.Student");

 // 获取所有的成员变量
  Field[] fields = c.getFields();
  Field[] fields1 = c.getDeclaredFields();
  for (Field field : fields1) {
  System.out.println(field);
  }

 /*
  * Person p = new Person(); p.address = "北京"; System.out.println(p);
  */

 // 通过无参构造方法创建对象
 Constructor con = c.getConstructor();
 Object obj = con.newInstance();
 System.out.println(obj);

 // 获取单个的成员变量
 //通过成员变量名
 Field nameField = c.getField("name");
 // public void set(Object obj,Object value)
 // 将指定对象变量上此 Field 对象表示的字段设置为指定的新值。
 nameField.set(obj, "小红"); // 给obj对象的addressField字段设置值为"北京"
 System.out.println(obj);

 // 获取age并对其赋值
 // NoSuchFieldException 私有变量
 Field ageField = c.getDeclaredField("age");
 // IllegalAccessException 暴力访问
 ageField.setAccessible(true);
 ageField.set(obj, 18);
 System.out.println(obj);

 }
}

运行结果:

反射获取成员方法

**类比上面Constructor类中的方法,这个类也有同样的方法,获取所有成员方法(返回数组),获取私有成员方法等 这里不再赘述 **

package com.reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

public class MethodDemo {
 public static void main(String[] args) throws Exception {
 // 获取字节码文件对象
 Class c = Class.forName("com.reflect.Student");

 // 获取所有的方法
  Method[] methods = c.getMethods(); // 获取自己的包括继承父亲的公共方法
  Method[] methods1 = c.getDeclaredMethods(); // 获取自己的所有的方法
  for (Method method : methods1) {
  System.out.println(method);
  }

 Constructor con = c.getConstructor();
 Object obj = con.newInstance();

 // 获取单个方法并使用
 // public void show()
 // public Method getMethod(String name,Class<?>... parameterTypes)
 // 第一个参数表示的方法名,第二个参数表示的是方法的参数的class类型
 Method m1 = c.getMethod("study");
 // public Object invoke(Object obj,Object... args)
 // 返回值是Object接收,第一个参数表示对象是谁,第二参数表示调用该方法的实际参数
 m1.invoke(obj); // 调用obj对象的m1方法

 System.out.println("----------");
 Method m2 = c.getDeclaredMethod("study", String.class);
 // NoSuchMethodException 访问私有方法 暴力访问
 m2.setAccessible(true);
 m2.invoke(obj, "数学");
 }
}

运行结果:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • java反射应用详细介绍

    本篇文章依旧采用小例子来说明,因为我始终觉的,案例驱动是最好的,要不然只看理论的话,看了也不懂,不过建议大家在看完文章之后,在回过头去看看理论,会有更好的理解. 下面开始正文. [案例1]通过一个对象获得完整的包名和类名 复制代码 代码如下: package Reflect; /** * 通过一个对象获得完整的包名和类名 * */ class Demo{ //other codes... } class hello{ public static void main(String[] args)

  • Java中的反射机制详解

    Java中的反射机制详解 反射,当时经常听他们说,自己也看过一些资料,也可能在设计模式中使用过,但是感觉对它没有一个较深入的了解,这次重新学习了一下,感觉还行吧! 一,先看一下反射的概念: 主要是指程序可以访问,检测和修改它本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义. 反射是Java中一种强大的工具,能够使我们很方便的创建灵活的代码,这些代码可以再运行时装配,无需在组件之间进行源代码链接.但是反射使用不当会成本很高! 看概念很晕的,继续往下

  • java中利用反射调用另一类的private方法的简单实例

    我们知道,Java应用程序不能访问持久化类的private方法,但Hibernate没有这个限制,它能够访问各种级别的方法,如private, default, protected, public. Hibernate是如何实现该功能的呢?答案是利用JAVA的反射机制,如下: import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class ReflectDemo {

  • java中如何反射获取一个类

    反射说白了就是可以获得一个类的所有信息,主要包括方法和属性两部分. 1.获得方法包括获得方法的名称,方法的返回类型,方法的访问修饰符,以及通过反射执行这个方法. 2.获得属性包括属性的名称,类型,访问修饰符,以及这个属性的值. 这些获得都有相应的API提供操作. 代码如下: package poi; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Meth

  • 一文搞懂Java中的反射机制

    前一段时间一直忙,所以没什么时间写博客,拖了这么久,也该更新更新了.最近看到各种知识付费的推出,感觉是好事,也是坏事,好事是对知识沉淀的认可与推动,坏事是感觉很多人忙于把自己的知识变现,相对的在沉淀上做的实际还不够,我对此暂时还没有什么想法,总觉得,慢慢来,会更快一点,自己掌握好节奏就好. 好了,言归正传. 反射机制是Java中的一个很强大的特性,可以在运行时获取类的信息,比如说类的父类,接口,全部方法名及参数,全部常量和变量,可以说类在反射面前已经衣不遮体了(咳咳,这是正规车).先举一个小栗子

  • 详解Java中的反射机制和动态代理

    一.反射概述 反射机制指的是Java在运行时候有一种自观的能力,能够了解自身的情况为下一步做准备,其想表达的意思就是:在运行状态中,对于任意一个类,都能够获取到这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性(包括私有的方法和属性),这种动态获取的信息以及动态调用对象的方法的功能就称为java语言的反射机制.通俗点讲,通过反射,该类对我们来说是完全透明的,想要获取任何东西都可以,这是一种动态获取类的信息以及动态调用对象方法的能力. 想要使用反射机制,就必须要先获取到该类

  • Java中的反射机制基本运用详解

    目录 Java中的反射机制基本运用 1.什么是反射(reflect) 2.反射机制提供的功能 3.反射->获取类对象 4.反射->利用无参构造实例化对象 5.反射->利用有参构造实例化对象 6.反射->调用无参方法 7.反射->调用有参方法 8.反射->访问私有方法 9.反射->类加载路径 总结 Java中的反射机制基本运用 看完反射可以了解一下注解 注解annotation://www.jb51.net/article/221276.htm 1.什么是反射(re

  • Java中的反射机制示例详解

    目录 反射 什么是Class类 获取Class实例的三种方式 通过反射创建类对象 通过反射获取类属性.方法.构造器 更改访问权限和实例赋值 运用场景 反射 反射就是把Java类中的各个成分映射成一个个的Java对象.即在运行状态中,对于任意一个类,都能够知道这个类的所以属性和方法:对于任意一个对象,都能调用它的任意一个方法和属性.这种动态获取信息及动态调用对象方法的功能叫Java的反射机制 每一个Java程序执行必须通过编译.加载.链接和初始化四个阶段 1.编译:将.java.文件编译成字节码.

  • java中的反射及其优点说明

    目录 java反射及优点 java反射机制(Reflection) 1.什么是反射?反射有什么作用? 2.反射相关的主要API 3.什么是Class类 4.调用运行时类的指定结构 java反射及优点 反射是java的一大特性,而且是有些框架实现了IoC/DI的原理,本文就来探讨下java中的反射及其优点. 首先是普通的java静态类加载,java静态类是通过new实现的,在编译时刻就要加载所有可能用到的类,这样实际上存在一些缺点的,比如只要有一个类没有找到或者出现重大的问题编译便不会通过,导致其

  • 10分钟带你理解Java中的反射

    一.简介 Java 反射是可以让我们在运行时获取类的方法.属性.父类.接口等类的内部信息的机制.也就是说,反射本质上是一个"反着来"的过程.我们通过new创建一个类的实例时,实际上是由Java虚拟机根据这个类的Class对象在运行时构建出来的,而反射是通过一个类的Class对象来获取它的定义信息,从而我们可以访问到它的属性.方法,知道这个类的父类.实现了哪些接口等信息. 二.Class类 我们知道使用javac能够将.java文件编译为.class文件,这个.class文件包含了我们对

  • Java中的反射,枚举及lambda表达式的使用详解

    目录 一.反射 1.1定义 1.2用途 1.3反射基本信息 1.4与反射相关的类 1.5Class类(反射机制的起源) 1.6Class类中的相关方法 1.7获得Class对象的三种方式 1.8反射的使用 1.9反射优点和缺点 二.枚举 2.1Enum类的常用方法 2.2枚举的优点和缺点 三.Lambda表达式 3.1Lambda表达式的语法及基本使用 3.2函数式接口 3.3变量捕获 总结 一.反射 1.1 定义 Java的反射(reflection)机制是在运行状态中,对于任意一个类,都能够

随机推荐