反射(一)

** 注:博主的这篇文章是在学习反射的时间写的如有问题请及时联系博主进行修改 **

何为反射

 这里也不说一些很官方的语言了,官方的说明看着头痛,总之一句话,就是在JAVA的运行状态的时候,可以对任何一个类进行操作,这是一个可以动态的获取信息和动态的使用某个方法的能力我们就叫他反射,在家看下名字就知道这项功能有多屌。

反射常用到的方法

注:Class类表示正在运行的JAVA应用程序的接口;Class类没有构造方法,是由java虚拟机自动创建的。

使用反射API

这里先例举几个常用到的方法,这些是我们这次教程所需要的方法,不是很多,其他的我在以后的文章中写出。

通过代码的方式来了解这些方法如何使用

首先我创建个Student.java的类,里面有三个属性(name,age,xb),看代码:
package net.cncandy.test;

public class Student {

    private String name;
    private int age;
    private boolean xb;
    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 boolean isXb() {
        return xb;
    }
    public void setXb(boolean xb) {
        this.xb = xb;
    }
    public Student(String name, int age, boolean xb) {
        super();
        this.name = name;
        this.age = age;
        this.xb = xb;
    }
    public Student() {

    }
}

接下来我们要创建一个测试的类,我给他取名字叫做TestDeom,你们可以根据自己来创建这个类哦。

我们需要认识三中获取类的方式:

  • 类名.class
  • Class.ForName 注:这个是一个方法,我们需要往里面传递参数,具体传入什么参数我接下来会说的呢,
  • 对象.getclass

当我们创建好了测试的类后,我们这里讲解的是反射,我们当然要通过反射的方式来加载到JVM,这里就需要我上面说的Class.forName的方式来加载,这个方法是返回的一个Class对象。

` Class studentClass = Class.forName("net.cncandy.test.Student"); `

> 参数这里面填写的是你的包名加上类的名字,返回的数据要**通过Class类型接受**。这个时候你使用System.out.println(studentClass);打印是不是发现控制台有显示出来类的信息。
比如我这里显示的是 **class net.cncandy.test.Student** 这里的信息和你可能显示不一样,可以我们的包名是不一样的,你要对应你自己的

分别通过该类的有参构造和无参构造来实例化对象

  类已经加载到了内存中了,我们是不是应该创建个Student的对象呢,我们都知道在平时普通的new一个对象的时候,其实默认是调用了该类的构造方法,那么这里也是如此我们也需要拿到该类的构造方法,这小结我们要需要如何获取类的构造方法:

  • 新增需要知识:获取构造方法
  • 使用的方法:getConstructor() 和 newInstance()

我们看下如何通过无参的构造来实例化对象,这里我们只需要使用Class的对象点出newInstance()即可,这样系统就会实例化一个对象。

问:我调用了newInstance(),是如何实例化对象的呢?上面说要通过构造函数,我也没有指定构造函数呀。
答:使用次方法系统会自动寻找类中的无参的构造方法,通过无参的构造来实例化对象。这里大家可以测试下,当你删除类中的无参构造时,你再次运行代码会出现错误。

            Class studentClass = Class.forName("net.cncandy.test.Student"); //加载类
            Student student = (Student)studentClass.newInstance(); //实际是使用的无参构造实例化对象
            student.setAge(16); //使用类中的方法
            System.out.println(student.getAge()); //输出值,验证是否成功复制

输出的结果是16,证明我们这种实例化对象的方法是对的

使用有参数的构造来实例化对象

  首先我们要先拿到带有参数的构造方法,在我上面写的方法列表内有相关的方法,我们这里使用的是getConstructor()来获取带参的构造,先来了解下代码:

            Constructor constructor =studentClass.getConstructor(String.class,int.class,boolean.class);
            Student student = (Student) constructor.newInstance("Candy",20,true);
            System.out.println(student.getAge());

这里大家看下的,在getConstructor()如果括号额你填的空则是使用的是空参数构造方法,填写参数的意思是因为我们每个类中可能会存在大量重名的方法,比如我们使用的方法重载,这里可以通过参数列表来区分使用的是哪一个方法。当你传入了参数的时候,在你使用newInstance时候你会发现代码有提示说让您传入参数,这里的参数就是你平时实例化对象时的实际参数。

如何通过反射来使用类中的方法

  我们这里可以通过参考上面通过有参数的构造来实例化对象的代码来处理使用类中的方法,其实这里的思路是一样的。遵循三个步骤(这里对于我来说的是那个步骤)1.拿到类中的方法(Look,反射屌不屌)2.给方法传递参数,3.测试是否成功。这里的获取方法的方法是需要传入两个参数
参数一:你需要的方法的名称
参数二:方法参数的类型,有多少写多少,反正代码里面接受的是三个点可编长参数。
最后使用invoke方法来进行使用方法,两个参数:
参数一:上面咱们实例化的student。
参数二:你需要往这个方法里面传的值

            Method method =  clzzClass.getDeclaredMethod("setAge", int.class);
            method.invoke(user, 20);
            System.out.println(user.getAge());

最后验证输出的是20

使用反射来操作属性

  上面方法表格里面给出了获取属性的方法getDeclaredField返回值是Field,我们这里可以直接通过这个方法传入需要获得的属性名字,

            Field field = studentClass.getDeclaredField("name");
            field.set(student, "Candy");
            System.out.println(student.getName());

当然我们在设置属性的值的时候我们是通过set方法来设置的这个里面需要传入两个参数,参数一:Student的对象,参数二:需要设置的值,运行程序可以正确的输出Candy。

注:这个获取属性的时候,如果有的属性在类中是私有的属性,那么我们在这里修改值的时候会爆出java.lang.IllegalAccessException异常,所以这里我们还要加一句代码setAccessible(true)这句话是避免安全检查,这里不做多的解释,有兴趣的可以看下源码。

JAVA之反射(一)的更多相关文章

  1. JAVA的反射理解

    1----------------------------反射的概念----------------------------------------------- JAVA的反射机制是在运行状态中,对 ...

  2. java的反射

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

  3. iOS运行时编程(Runtime Programming)和Java的反射机制对比

    运行时进行编程,类似Java的反射.运行时编程和Java反射的对比如下:   1.相同点   都可以实现的功能:获取类信息.属性设置获取.类的动态加载(NSClassFromString(@“clas ...

  4. Java 类反射机制分析

    Java 类反射机制分析 一.反射的概念及在Java中的类反射 反射主要是指程序可以访问.检测和修改它本身状态或行为的一种能力.在计算机科学领域,反射是一类应用,它们能够自描述和自控制.这类应用通过某 ...

  5. java的反射机制

    一.java的反射机制浅谈 最近研究java研究得很给力,主要以看博文为学习方式.以下是我对java的反射机制所产生的一些感悟,希望各位童鞋看到失误之处不吝指出.受到各位指教之处,如若让小生好好感动, ...

  6. Java:反射

    初识Java反射机制: 从上面的描述可以看出Java的反射机制使得Java语言可以在运行时去认识在编译时并不了解的类/对象的信息,并且能够调用相应的方法或修改属性的值.Java反射机制的核心就是允许在 ...

  7. Java中反射机制和Class.forName、实例对象.class(属性)、实例对象getClass()的区别

    一.Java的反射机制   每个Java程序执行前都必须经过编译.加载.连接.和初始化这几个阶段,后三个阶段如下图:   其中

  8. java笔记--反射进阶之总结与详解

    一.反射进阶之动态设置类的私有域 "封装"是Java的三大特性之一,为了能更好保证其封装性,我们往往需要将域设置成私有的, 然后通过提供相对应的set和get方法来操作这个域.但是 ...

  9. java笔记--反射机制之基础总结与详解

    一.反射之实例化Class类的5种方式: java的数据类型可以分为两类,即引用类型和原始类型(即基本数据类型). 对于每种类型的对象,java虚拟机会实例化不可变的java.lang.Class对象 ...

  10. Java中反射的三种常用方式

    Java中反射的三种常用方式 package com.xiaohao.test; public class Test{ public static void main(String[] args) t ...

随机推荐

  1. Python-获取前一条用例的执行结果

    import unittest,HTMLTestRunner from nose_parameterized import parameterized def login(username,passw ...

  2. Servlet简单增删改查

    前台页面是别人给的. 例子: package cn.itcast.cus.dao; import java.sql.SQLException; import java.util.ArrayList; ...

  3. codeforces 622B B. The Time

    B. The Time time limit per test 1 second memory limit per test 256 megabytes input standard input ou ...

  4. 输入框input内容变化与onpropertychange事件的兼容

    一.输入框常用的几个事件 onblur 元素失去焦点. onchange 域的内容被改变. onclick 当用户点击某个对象时调用的事件句柄. ondblclick 当用户双击某个对象时调用的事件句 ...

  5. 2016北京集训 小Q与进位制

    题目大意 一个数每一位进制不同,已知每一位的进制,求该数的十进制表达. 显然有 $$Ans=\sum\limits_{i=0}^{n-1}a_i \prod\limits_{j=0}^{i-1}bas ...

  6. org.springframework.web.client.HttpClientErrorException: 400 null

    异常代码: org.springframework.web.client.HttpClientErrorException: 400 null 已解决. 百度了一下400代表无法解析请求. 说明请求是 ...

  7. Python:删除字符串中的字符

    一.删除字符串两端的一种或多种字符 #strip().lstrip().rstrip()方法:(默认删除空格符) A.list.strip(字符):删除字符串两端的一种或多种字符: #例:删除字符串s ...

  8. VS Code:快捷方式

    转于:vscode: Visual Studio Code 常用快捷键 博主:魚魚 更多操作参见官网:https://code.visualstudio.com/docs/getstarted/key ...

  9. MySQL Sending data导致查询很慢的问题详细分析

    这两天帮忙定位一个MySQL查询很慢的问题,定位过程综合各种方法.理论.工具,很有代表性,分享给大家作为新年礼物:) [问题现象] 使用sphinx支持倒排索引,但sphinx从mysql查询源数据的 ...

  10. 用python做的windows和linx文件夹同步。解决自动同步、加快传输大量小文件的速度、更丰富的文件上传过滤设置。

    现在工具不好用,用的pycharm自动同步,但对于git拉下来的新文件不能自动上传到linux,只有自己编辑过或者手动ctrl + s的文件才会自动同步.导致为了不遗漏文件,经常需要全量上传,速度非常 ...