黑马学习笔记_Java 反射技术

  ——- android培训java培训、期待与您交流! ———-

反射

1 反射的概述

  • java反射机制是运行状态中,对于任意一个类,都能够知道这类的所有属性和方法;
  • 对于任意一个对像,都能够调用它的任意一个方法和属性;
  • 这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制;
  • 要想解剖一个类,必须先要获取到该类的字节码文件对象;
  • 而解剖使用的就是Class类中的方法,所以先要获取到每一个字节码文件对应的Class类型的对象;

2 反射中常用的类

  • Class类:Class类十分特殊,当一个class被加载jvm便会自动产生一个Class对象。Class 类的实例表示正在运行的 Java 应用程序中的类和接口。基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也表示为 Class 对象。Class 没有公共构造方法

  • Field类:用户描述java类中的成员变量,

  • Method类:用户描述java类中的成员方法

  • Constructor 提供关于类的单个构造方法的信息以及对它的访问权限

3 反射的应用场景

反射是框架中常用的方法:
对于WEB框架,开发人员在配置文件中定义他们对各种接口和类的实现,通过反射机制,框架能够快速的动态初始化所需要的类。

例如,Spring框架使用如下的配置文件:

<bean id="someID" class="com.tplinking.domain">
    <property name="someField" value="someValue"/>
</bean>

当Spring容器处理元素时,会使用Class.forName(“com.tplinking.domain”)来初始化这个类,并再次使用反射获取元素对应的setter方法,为对象的属性赋值。

Servlet也会使用相同的机制:

<servlet>
    <servlet-name>someServlet</servlet-name>
    <servletclass>
        com.programcreek.WhyReflectionServlet
    </servlet-class>
<servlet>

4 如何使用反射

让我们同过几个典型的案例来学习如何使用反射

package cn.itcast.bean;

public class Student {
    public int age;

    public String name;

    public Student() {
        super();
        System.out.println("construct Student run");
    }

    public Student(int age, String name) {
        super();
        this.age = age;
        this.name = name;
        System.out.println("construct Student param run....");
    }

    public void show() {
        System.out.println(name + "...show run...." + age);
    }

    private void method() {
        System.out.println("method run");
    }

    public void paramMethod(int num, String str) {
        System.out.println(num + "...paramMethod...." + str);
    }

    public static void staticMethod() {
        System.out.println("static method run....");
    }

}
  • 实例1:获取字节码对象的3种方式
package cn.itcast.reflect.demo;

import cn.itcast.bean.Student;

public class Test {
    public static void main(String[] args) throws Exception {

         //通过该对象,调用object的getClass()方法来获取字节码文件对象
         Student p1 = new Student();
         Class<? extends Student> clazz1 = p1.getClass();
         System.out.println(p1);

         //通过调用该类的class属性来获取字节码文件对象
         Class clazz2 = Student.class;
         System.out.println(clazz2);

         //直接通过Class的forName()来获取该字符串表示的字节码文件对象
         Class clazz3 = Class.forName("cn.itcast.bean.Student");

    }
}
  • 实例2:通过反射创建对象
package cn.itcast.reflect.demo;

import java.lang.reflect.Constructor;
import cn.itcast.bean.Student;

public class Test {
    public static void main(String[] args) throws Exception {

        //通过反射调用无参数的构造方法
        Class clazz1 = Class.forName("cn.itcast.bean.Student");
        Object object1 = clazz1.newInstance();
        System.out.println(object1);

        //通过反射调用有参数的构造方法
        Class<?> clazz2 = Class.forName("cn.itcast.bean.Student");
        //获取构造方法对象
        Constructor<?> constructor = clazz2.getConstructor(int.class,
                String.class);
        Object object2 = constructor.newInstance(2, "小强");
        System.out.println(object2);

    }
}
  • 实例3:通过反射调用类中的方法
package cn.itcast.reflect.demo;

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

public class Test {

    public static void main(String[] args) throws Exception {
        getMethodDemo();
    }

    /**
     * 通过反射调用类中的有参方法
     * @throws Exception
     */
    public static void getMethodDemo_3() throws Exception {

        Class<?> clazz = Class.forName("cn.itcast.bean.Student");
        Method method = clazz.getMethod("paramMethod", int.class, String.class);
        Object obj = clazz.newInstance();
        method.invoke(obj, 89, "小强");
    }

    /**
     * 获取空参数的成员方法 
     * @throws Exception
     */
    public static void getMethodDemo_2() throws Exception {
        Class<?> clazz = Class.forName("cn.itcast.bean.Student");
        Method method = clazz.getMethod("show", null);// 获取空参数一般方法。
        // Object obj = clazz.newInstance();
        Constructor constructor = clazz.getConstructor(int.class, String.class);
        Object obj = constructor.newInstance(37, "小明");

        method.invoke(obj, null);

    }

    /**
     * 获取指定Class中的所有方法。
     * @throws Exception
     */
    public static void getMethodDemo() throws Exception {

        Class clazz = Class.forName("cn.itcast.bean.Student");

        Method[] methods = clazz.getMethods();// 获取的都是公有的方法。
        methods = clazz.getDeclaredMethods();// 只获取本类中所有方法,包含私有。
        for (Method method : methods) {
            System.out.println(method);
        }
    }

}
  • 实例4:通过反射调用类中的字段
package cn.itcast.reflect.demo;

import java.lang.reflect.Field;

public class Test {

    /**
     * 通过反射获取类中的字段
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {
        getFieldDemo();
    }

    /**
     * 获取字节码文件中的字段。
     * @throws Exception
     */
    public static void getFieldDemo() throws Exception {

        Class<?> clazz = Class.forName("cn.itcast.bean.Student");

        Field field = null;// clazz.getField("age");//只能获取公有的,
        field = clazz.getDeclaredField("age");// 只获取本类,但包含私有。

        //创建对象
        Object obj = clazz.newInstance();

        //为对象中的成员变量赋值
        field.set(obj, 89);

        //获取对象的中的成员变量的值
        Object o = field.get(obj);
        System.out.println(o);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值