zoukankan      html  css  js  c++  java
  • java中的反射

    一.什么是反射,反射有什么用

      以前我们创建对象有几种方式?只有一种方式去new一个对象。有的时候在程序的开发阶段,你并不知道要创建哪
    个类的对象,或者你不知道要调用类的哪个方法,或者访问类的哪个属性。在程序的运行阶段,你才知道要创建哪
    个类的对象。那怎么解决这种问题?
    研究一下spring的核心的源码的业务逻辑,分以下几个步骤
      1,读取applicationContext.xml,获取所有的bean标签的class属性
      2,获取bean标签的class属性之后,class属性的值在java程序中应该以什么数据类型来存储,用字符串类型来存储
      3,根据class属性的字符串描述符来创建一个这个描述符描述的对象。需求到这一步,就变成:
      根据一个字符串,来创建一个字符串描述的对象。
    使用反射必须先获取类的Class对象,每个类在java的虚拟机中,默认都会存在一个class的对象。如果要使用反
    射,必须先获取这个Class对象。
    二.class对象的使用
      1.Class对象获取的三种方式
    创建Person.java
    package com.aaa.spring.entity;
    /**
    * 人员类
    */
    public class Person {
    }
    /**
    * Class对象获取的三种方式
    */
    public class Test02 {
    public static void main(String[] args) throws Exception {
    //获取Person的Class对象
    //第一种方式,通过Class.forName()
    Class clazz1 = Class.forName("com.aaa.spring.entity.Person");
    System.out.println(clazz1);
    //第二种方式 访问类的class对象
    Class clazz2 = Person.class;
    System.out.println(clazz2);
    //第三种方式,通过对象的getClass方法
    Person person = new Person();
    Class clazz3 = person.getClass();
    System.out.println(clazz3);
    }
    }

      2.利用Class对象获取构造方法

    创建Person2.java

    package com.aaa.spring.entity;
    public class Person2 {
    //默认无参的构造
    public Person2(){}
    //公共的有一个参数的方法
    public Person2(String name){}
    //私有的有两个参数的方法
    private Person2(String name,int age){}
    }
    /**
    * 利用CLass对象获取构造方法
    */
    public class Test03 {
    public static void main(String[] args) throws Exception {
    //获取类的Class对象
    Class clazz = Person2.class;
    //获取类的所有公共的构造方法
    Constructor[] constructors = clazz.getConstructors();
    for (Constructor con :
    constructors) {
    System.out.println(con);
    }
    System.out.println("===");
    //获取类的所有的声明的构造方法
    Constructor[] declaredConstructors = clazz.getDeclaredConstructors();
    for (Constructor con :
    declaredConstructors ) {
    System.out.println(con);
    }
    //根据参数获取指定的构造方法
    System.out.println("获取指定一个参数的公共的构造方法:");
    Constructor con1 = clazz.getConstructor(String.class);
    System.out.println(con1);
    System.out.println("获取两个参数的私有的构造方法:");
    Constructor con2 = clazz.getDeclaredConstructor(String.class, int.class);
    System.out.println(con2);
    }
    }

      3.利用Class对象获取类的方法

    创建Person3.java

    package com.aaa.spring.entity;
    public class Person3 {
    public void info(){
    System.out.println("我是一个无参的公共方法");
    }
    public void info(String name,int age){
    System.out.println("我是一个有两个参数的额公共方法");
    }
    private void info(String name){
    System.out.println("我是一个有一个参数的私有的方法");
    }
    }
    /**
    * 利用Class对象获取方法
    */
    public class Test04 {
    public static void main(String[] args) throws Exception {
    //获取类的Class对象
    Class clazz = Person3.class;
    Method[] methods = clazz.getMethods();
    System.out.println("获取类的所有的公共的方法,包含父类的方法:");
    for (Method method:
    methods) {
    System.out.println(method);
    }
    System.out.println("获取所有的声明的方法:");
    Method[] declaredMethods = clazz.getDeclaredMethods();
    for (Method method:
    declaredMethods) {
    System.out.println(method);
    }
    System.out.println("获取两个参数的公共的方法:");
    Method method = clazz.getMethod("info",String.class,int.class);
    System.out.println(method);
    System.out.println("获取一个参数的私有的方法:");
    Method method2 = clazz.getDeclaredMethod("info",String.class);
    System.out.println(method2);
    }
    }

      4.利用Class对象获取类的属性

    创建Person4.java

    package com.aaa.spring.entity;
    public class Person4 extends Person{
    public String name;
    private int age;
    }
    public class Test05 {
    public static void main(String[] args) throws
    Exception{
    //获取类的Class对象
    Class clazz = Person4.class;
    System.out.println("获取类的所有公共的属性(也包括父类中的公共的属性):");
    Field[] fields = clazz.getFields();
    for (Field field :
    fields) {
    System.out.println(field);
    }
    System.out.println("获取类的所有声明的属性:");
    Field[] declaredFields = clazz.getDeclaredFields();
    for (Field field:
    declaredFields ) {
    System.out.println(field);
    }
    //获取公共的name属性
    System.out.println("获取公共的name属性");
    Field name = clazz.getField("name");
    System.out.println(name);
    System.out.println("获取私有的age属性:");
    Field age = clazz.getDeclaredField("age");
    System.out.println(age);
    }
    }

      5.利用Class对象创建类的实例

    创建Person5.java

    package com.aaa.spring.entity;
    public class Person5 {
    private String name;
    //默认无参的构造
    public Person5(){}
    //公共的有一个参数的方法
    public Person5(String name){
    this.name=name;
    }
    //私有的有两个参数的方法
    private Person5(String name,int age){}
    public void info(){
    System.out.println(name);
    }
    }
    /**
    * 利用CLass对象创建类的实例
    */
    public class Test06 {
    public static void main(String[] args) throws Exception {
    //获取类的class对象
    Class clazz = Class.forName("com.aaa.spring.entity.Person5");
    //创建类的对象有两种方式
    //第一种,调用Class对象的newInstance方法,该方法会会调用类的默认的无参的构造
    Person5 person51 =(Person5) clazz.newInstance();
    System.out.println(person51);
    //第二种,根据类的构造方法对象创建类的实例
    Constructor constructor = clazz.getConstructor(String.class);
    Person5 person52 = (Person5)constructor.newInstance("zhangsan");
    System.out.println(person52);
    person52.info();
    Constructor con2 = clazz.getDeclaredConstructor(String.class, int.class);
    //设置忽略构造方法的访问级别
    con2.setAccessible(true);
    Person5 person53 = (Person5)con2.newInstance("zhangsan", 18);
    person53.info();
    }
    }

      6.利用Class对象调用类的方法

    创建Person6.java

    package com.aaa.spring.entity;
    public class Person6 {
    public void info(){
    System.out.println("我是一个无参的公共方法");
    }
    public void info(String name,int age){
    System.out.println("我是一个有两个参数的额公共方法");
    }
    private void info(String name){
    System.out.println("我是一个有一个参数的私有的方法");
    }
    }
    /**
    * 利用Class对象访问类的方法
    */
    public class Test07 {
    public static void main(String[] args) throws Exception {
    Person6 p6 = new Person6();
    p6.info();
    p6.info("zhangsan",12);
    //获取类的Class对象
    Class clazz = Class.forName("com.aaa.spring.entity.Person6");
    //利用反射创建对象
    Object p61 = clazz.newInstance();
    //获取info()方法
    Method info = clazz.getMethod("info");
    //调用用法
    info.invoke(p61);
    //获取info(string,int)这个方法
    Method info1 = clazz.getMethod("info", String.class, int.class);
    //调用方法
    info1.invoke(p61,"张三",16);
    //利用反射调用类的私有的方法
    Method info2 = clazz.getDeclaredMethod("info",String.class);
    //忽略方法的访问级别
    info2.setAccessible(true);
    //调用方法
    info2.invoke(p61,"李四");
    }
    }

      7.利用Class对象返回类的属性

    创建Person7.java

    package com.aaa.spring.entity;
    public class Person7 {
    public String name="zhangsan";
    private int age=12;
    }
    /**
    * 利用Class对象访问类的属性
    */
    public class Test08 {
    public static void main(String[] args) throws Exception {
    Person7 p = new Person7();
    String name = p.name;
    System.out.println(name);
    p.name="lisi";
    System.out.println(p.name);
    //获取类的CLass对象
    Class clazz = Class.forName("com.aaa.spring.entity.Person7");
    //获取对象的属性值,打印出来
    //创建对象
    Object p1 = clazz.newInstance();
    //获取类的属性的对象
    Field f1 = clazz.getField("name");
    //设置属性的值
    f1.set(p1,"lisi");
    //获取属性的值
    Object name1 = f1.get(p1);
    System.out.println(name1.toString());
    Field f2 = clazz.getDeclaredField("age");
    //忽略访问级别
    f2.setAccessible(true);
    System.out.println(f2.get(p1));
    }
    }
  • 相关阅读:
    Spark Streaming企业运用
    spark企业运用
    sparkcore企业运用
    Spark GraphX从入门到实战
    sparkstreaming入门到实战
    sparkSql从入门到实战
    sparkcore入门到实战
    spark机器算法从入门到实战
    flink实时数仓从入门到实战
    github上克隆私有项目
  • 原文地址:https://www.cnblogs.com/duguangming/p/10913896.html
Copyright © 2011-2022 走看看