Spring基础之 反射(Reflection)

1.了解Class

package com.inspire.reflection.Class_api;

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

public class ClassUtils {
    public static void main(String[] args) {
        String s="abc";
        printclassFieldMessage(s);
        printClassMethodMessage(s);
    }
    /**
     * 打印类的信息,成员方法
     * @param obj  该对象所属类的信息
     */
    public static void printClassMethodMessage(Object obj){
        //获取类的信息,获取类的类类型
        Class c1=obj.getClass();//传递的哪个子类的对象,c就是该子类的类类型
        //获取类的名称
        System.out.println("类名是:"+c1.getName());
        //获取方法
        /*
        Method类,方法的对象
        一个成员方法就是一个Method对象
        getMethods方法获取的是所有的public的方法,包括父类继承而来的
        getDeclaredMethods方法获取的是所有该类自己定义的方法。不问访问权限
         */
        Method[] methods=c1.getMethods();
//        Method[] method=c1.getDeclaredMethods();
        for (int i = 0; i <methods.length ; i++) {
            //获取方法的返回值类型的类类型(比如返回String类型,返回的是String.class)
            Class returnType=methods[i].getReturnType();
            System.out.print(returnType.getName()+" ");

            //获取方法的名称
            System.out.print(methods[i].getName()+"(");

            //获取参数类型   获取的是参数列表类型的类类型
            Class[] paramType=methods[i].getParameterTypes();

            for (Class c:paramType) {
                System.out.print(c.getName()+",");
            }
            System.out.println(")");
        }
    }
    /**
     * 打印类的信息,成员变量
     * @param obj
     */
    public static void printclassFieldMessage(Object obj) {
        //获取成员变量
        /**
         * 成员变量也是对象
         * java.lang.reflect.Field
         * Field封装了关于成员变量的操作
         * getFields方法获取的是所有的public的成员变量信息
         * getDeclaredFields()获取的是该类自己声明的成员信息(public/private)
         */
        Class c1=obj.getClass();//传递的哪个子类的对象,c就是该子类的类类型
        //Field[] fields=c1.getFields();
        Field[] fields=c1.getDeclaredFields();
        for (Field f:fields) {
            //得到成员变量类型的类类型
            Class fieldType=f.getType();
            //得到成员变量的名称
            String typeName=f.getName();
            System.out.println(typeName+" "+fieldType);
        }
    }
    /**
     * 打印对象的构造函数的信息
     * @param obj
     */
    public static void printClassConMessage(Object obj){
        Class c=obj.getClass();
        /*
        构造函数也是对象
        java.lang.Constructor中封装了构造函数的信息
        getDeclaredConstructor获取自己声明的构造函数
         */
        Constructor[] constructors=c.getDeclaredConstructors();
        //Constructor[] constructors=c.getConstructors();
        for (Constructor constructor:constructors) {
            System.out.println(constructor.getName()+"(");
            //获取构造函数的参数列表
            Class[] paramType=constructor.getParameterTypes();
            for (Class c1:paramType) {
                System.out.print(c1.getName()+",");
            }
            System.out.println(")");
        }
    }
}

2.获取一个类的类对象

(1).定义一个类

public class Student {
    private int id;
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    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;
    }

    private int age;

}

(2).获取类对象

public class ClassDemo1 {
    public static void main(String[] args) {
        //Student的实例对象如何表示?
       // Student student=new Student();
        /*Student也是实例对象,是Class类的实例对象。如何表示?
        任何一个类都是Class类的实例对象,都有三种表示方法
        */
        //方式一:任何一个类都有一个隐含的静态成员class
        Class c1=Student.class;
        //方式二:已知该类的对象,通过getClass方法
        Student student=new Student();
        Class c2=student.getClass();
        /*
         c1,c2表示了Student类的类类型(Class type)
         万事万物皆对象
         类也是对象,是Class类的实例对象
         这个对象我们称为该类的类类型
          */
        //c1,c2都代表了Student类的类类型,一个类只可能是Class类的一个实例对象
        System.out.println(c1==c2);  //true
        //方式三:
        try {
            Class c3=Class.forName("com.inspire.reflection.Class_object.Student");
            System.out.println(c2==c3);  //true
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        /*
        有了类的类类型,我们可以通过类类型创建该类的对象.即通过c1,c2,c3创建对象
         */
        try {
            Student student1= (Student) c1.newInstance();
            //调用方法
            student1.getAge();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}

3.通过反射调用方法

public class Printer {

    public void printA(){
        System.out.println("无参的方法..........");
    }
    public void printA(int a,int b){
        System.out.println(a+":"+b);
    }

}
public class MethodDemo {
    public static void main(String[] args) {
        Printer printer=new Printer();
        Class c=printer.getClass();
        try {
            //获取方法
            Method method= c.getDeclaredMethod("printA", int.class, int.class);//获取自己声明的方法
            //c.getMethod("printA", int.class, int.class);//获取public的方法
            //方法的反射操作
            method.invoke(printer,1,3); //放回方法的返回值
            System.out.println("=========================");
            Method method1=c.getDeclaredMethod("printA");
            method1.invoke(printer);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

4.通过反射理解泛型

java中泛型是防止错误输入的。只在编译时有效。编译之后集合的泛型是去泛型化的
public static void main(String[] args){
        ArrayList<String> list1=new ArrayList<String>();
        list1.add("hello");
     ArrayList list2=new ArrayList<String>();
     //System.out.println(c1==c2);//结果为true,说明编译之后集合的泛型是去泛型化的
        Class c2=list1.getClass();
        try {
            Method method=c2.getMethod("add", Object.class);
        //注意这里:虽然上面定义list1时是String类型的,但是这里可以加入int类型的数据
            method.invoke(list1,100);
            System.out.println(list1.size());
            System.out.println(list1);//不能用foreach遍历,类型不一样了
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

原文地址:https://www.cnblogs.com/inspred/p/8908609.html

时间: 2024-10-25 00:35:16

Spring基础之 反射(Reflection)的相关文章

代理(Proxy)和反射(Reflection)

前面的话 ES5和ES6致力于为开发者提供JS已有却不可调用的功能.例如在ES5出现以前,JS环境中的对象包含许多不可枚举和不可写的属性,但开发者不能定义自己的不可枚举或不可写属性,于是ES5引入了Object.defineProperty()方法来支持开发者去做JS引擎早就可以实现的事情.ES6添加了一些内建对象,赋予开发者更多访问JS引擎的能力.代理(Proxy)是一种可以拦截并改变底层JS引擎操作的包装器,在新语言中通过它暴露内部运作的对象,从而让开发者可以创建内建的对象.本文将详细介绍代

代理(Proxy)和反射(Reflection) (转)

转自:http://www.cnblogs.com/xiaohuochai/p/7268600.html 前面的话 ES5和ES6致力于为开发者提供JS已有却不可调用的功能.例如在ES5出现以前,JS环境中的对象包含许多不可枚举和不可写的属性,但开发者不能定义自己的不可枚举或不可写属性,于是ES5引入了Object.defineProperty()方法来支持开发者去做JS引擎早就可以实现的事情.ES6添加了一些内建对象,赋予开发者更多访问JS引擎的能力.代理(Proxy)是一种可以拦截并改变底层

C#基础|初探反射

什么是反射 我们编写的C#代码都可以编译成exe文件或dll文件.暂时先把他们叫做程序集吧,程序集中包含了很多信息.你写了一个类,类中会有字段,有属性,有方法,编译是会把这些信息保存在程序集中,暂时把这些信息叫做程序类型信息吧.可以肯定的是程序集中包含了程序类型信息. 程序类型信息有一个更加专业的术语叫"元数据"(metadata),他们就保存在程序集中. 顺着前面的前景提要,来给反射下一个定义吧. 一个程序在运行时,查看其他程序集或本身的元数据的行为叫做反射 反射实战,创建Type类

JAVA基础知识|反射

一.理解反射 1.1.基础概念 反射:在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性:这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制. "运行状态",如何理解? "运行状态"体现了反射的应用场景,当一些类,不需要提前加载进JVM内存,而是在运行时根据需要进行加载的时候,就可以通过反射进行动态加载 1.2.如何理解反射? 学习过java的童鞋,肯定对spring.hibernate一

Spring Boot实战(1) Spring基础

1. Spring基础配置 Spring框架本身有四大原则: 1) 使用POJO进行轻量级和最小侵入式开发 2) 通过依赖注入和基于接口编程实现松耦合 3) 通过AOP和默认习惯进行声明式编程 4) 使用AOP和模板(template)减少模式化代码 所谓依赖注入指的是容器负责创建对象和维护对象间的依赖关系,而不是通过对象本身负责自己的创建和解决自己的依赖.依赖注入主要目的是为了解耦. Spring Ioc容器(ApplicationContext)负责创建Bean,并通过容器将功能类Bean注

Spring基础(3)--- Spring基础配置

Spring 基础配置 Sprin框架本身有四大原则: 使用POJO进行轻量级和最小侵入式开发. 通过依赖注入和基于接口编程实现松耦合. 通过AOP实现默认习惯进行声明式编程. 使用AOP和模板(template)减少模块化代码. Spring 所有的功能的设计和实现都是基于此四大原则的. 1.依赖注入 1.1.理论 我们经常说的控制反转(IOC)和依赖注入(DI)在Spring环境下是两个等同的概念,控制反转是通过依赖注入实现的.所谓依赖注入是指容器在负责创建对象和维护对象间的依赖关系,而不是

第65节:Java后端的学习之Spring基础

Java后端的学习之Spring基础 如果要学习spring,那么什么是框架,spring又是什么呢?学习spring中的ioc和bean,以及aop,IOC,Bean,AOP,(配置,注解,api)-springFramework. 各种学习的知识点: spring expression language spring integration spring web flow spring security spring data spring batch spring网站: http://sp

C#反射Reflection

反射就是动态获取程序集中的元数据,直接通过.dll来创建对象,调用成员. Type是反射一个重要的类.通过Type获取类中所有信息,包括方法,属性等. 一.Type的简单使用 1.通过typeof(类型名)或类实例.GetType()的方式获取某个类型的Type. 2.通过GetFields方法可以获取类型中的所有属性. 3.Activator.CreateInstance(类型的Type)可以创建类型的实例. 4.IsInstanceOfType(),判断是否是某一类型的的实例. 5.IsAs

Spring基础系列11 -- 自动创建Proxy

Spring基础系列11 -- 自动创建Proxy 转载:http://www.cnblogs.com/leiOOlei/p/3557964.html 在<Spring3系列9- Spring AOP——Advice>和<Spring3系列10- Spring AOP——Pointcut,Advisor拦截指定方法>中的例子中,在配置文件中,你必须手动为每一个需要AOP的bean创建Proxy bean(ProxyFactoryBean). 这不是一个好的体验,例如,你想让DAO层