栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

反射:框架设计的灵魂

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

反射:框架设计的灵魂

反射:框架设计的灵魂

框架:半成品软件,可以在框架的基础上进行软件开发,简化编码

反射:将类的各自组成部分封闭为其他对象,这就是反射机制。

2.1:反射好处:
  • 可以在程序运行过程中,操作这些对象
  • 可以解耦,提高程序 的可扩展性


ClassLoader:是类加载器

**上述的图是Java代码在计算机的三个阶段:**也是 反射中获取Class对象的三种方式(每个阶段有一个方式)

1》Scource源代码阶段:

Java代码通过javac编译后变成java.class文件

java代码和java.class的这些文件都是在硬盘中

**2》Class类对象阶段:**通过类加载器将java.class封装成相应的对象,如:

成员变量 :Field[] fields (将成员变量封装成Field对象并且是一个数组)

构造方法:Constructor[] cons (将构造方法封装成Constructor对象并且是一个数组)

成员方法:Method[] methods (将成员方法封装成Method对象并且是一个数组)

3》目的是想加载进入内存被执行:

Runtime运行时阶段:

通过创建对象完成加载进入内存,被执行。

**2.2:获取Class对象的三种方式:

上述的图是Java代码在计算机的三个阶段:也是 反射中获取Class对象的三种方式(每个阶段有一个方式)

  1. Class.forName(“全包名”):将字节码文件加载进入内存,返回Class对象(注意的是:forName是静态方法可以通过类名.调用)

    • 多于用配置文件,将类名定义在配置文件中,读取文件加载类
    //Class.forName("全包名"):将字节码文件加载进入内存,返回Class对象;全包名=包名+类名
    Class aClass = Class.forName("com.haikang.person.Person");
    System.out.println(aClass);
    
  2. 类名.class:通过类名的属性class获取

    • 多用于参数的传递
    //2. 类名.class:通过类名的属性class获取
    Class personClass = Person.class;
    System.out.println(personClass);
    
  3. 对象.getClass():getClass()方法在Object类中定义中

    • 多用于对象的获取字节码的方式
    // 3. 对象.getClass():getClass()方法在Object类中定义中
    Person person = new Person();
    System.out.println(person);
    

结论:

同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,无论通过哪一种方式获取的Class对象都是同一个,也就是hashCode值相同。

package com.haikang.person;

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

    public Person() {
    }

    public Person(String name, int id) {
        this.name = name;
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
}
package com.haikang.reflect;

import com.haikang.person.Person;

public class ReflectClass {
    

    public static void main(String[] args) throws Exception {
        //Class.forName("全包名"):将字节码文件加载进入内存,返回Class对象;全包名=包名+类名
        Class aClass = Class.forName("com.haikang.person.Person");
        System.out.println(aClass);

        //2. 类名.class:通过类名的属性class获取
        Class personClass = Person.class;
        System.out.println(personClass);

        // 3. 对象.getClass():getClass()方法在Object类中定义中
        Person person = new Person();
        Class aClass1 = person.getClass();
        System.out.println(aClass1);

        System.out.println(aClass==personClass);
        System.out.println(aClass==aClass1);//等等号是比较地址

        System.out.println(aClass.hashCode());
        System.out.println(aClass1.hashCode());
        System.out.println(personClass.hashCode());
        //hashCode值相同说明是同一个对象

    }
}

2.3:Class对象功能:

获取功能:

  1. 获取成员变量们:

    Field[] getFields();

    Field getField(String name)

    Field[] getDeclaredFields();

    Field getDeclaredField(String name)

package com.haikang.reflect;

import com.haikang.person.Person;

import java.lang.reflect.Field;

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

        //获取PersonClass对象:
        Class aClass = Person.class;

        // Field[] 	getFields();只能获取publci修饰的成员变量
        Field[] fields = aClass.getFields();
        for (Field f:
             fields) {
            System.out.println(f);
            
        }

        Field string = aClass.getField("string");
        
        Person person = new Person();
        Object o = string.get(person);
        System.out.println(o);//haikang

        
        string.set(person,"eeje");
        System.out.println(person.toString());


        Field[] fields1 = aClass.getDeclaredFields();//说明getDeclaredFields()方法能获取所有成员方法
        for (Field f1:
             fields1) {
            System.out.println(f1);
            
        }


        Field name = aClass.getDeclaredField("name");
        

        //暴力反射:忽略访问权限修饰符的安全检查;要想获取反射get值,必须在get前进行暴力反射
        name.setAccessible(true);
        Object o1 = name.get(new Person());
        System.out.println(o1);

        Field id = aClass.getDeclaredField("id");
        id.setAccessible(true);
        Object o2 = id.get(person);
        System.out.println(o2);
    }
}

Field:成员变量的结果:

​ 操作

  1. 设置值:

    • void set(Object obj,Object value)
  2. 获取值:

    • get(Object obj)
  3. 忽略访问权限修饰符的安全检查:

    • setAccessible(true);//暴力反射
      

2.获取构造方法们:

Constructor[] getConstructors();

constructor getConstructor(类…parameterTypes)

Constructor[] getDeclaredConstructors();

Constructor getDeclaredConstructor(类…parameterTypes)

Constructor:构造对象

创建对象:

  • T newInstance(Object…initarges)

如果使用空参构造方法创建对象,操作可以简化:Class对象的newInstance()方法

下面该方法用于生成对象的:

    • TnewInstance(Object... initargs) 使用此 Constructor对象表示的构造函数,使用指定的初始化参数来创建和初始化构造函数的声明类的新实例.

手写代码区:私有构造方法方法的目的只有一个,就是不让其他类创建该类对象

package com.haikang.reflect;

import com.haikang.person.Person;
import org.junit.Test;

import java.lang.reflect.Constructor;

public class ReflectConstructor {

    

    @Test
    //生成有参对象
    public void test1()  throws Exception{
        //获取Person字节码对象
        Class aClass = Person.class;
        //获取构造器:
        Constructor constructor = aClass.getConstructor(String.class,int.class,String.class);
        //生成Person对象(是有参的)
        Person person = constructor.newInstance("海康", 18, "eeje");
        System.out.println(person);
    }


    //生成无参对象;无参生成对象有两种方式:一种是getConstructor()、一种是Class对象.newInstance()(在开发中建议使用用这种)
    @Test
    public void test2() throws Exception{
        //获取Person字节码对象
        Class personClass = Person.class;
        //获取构造器
        Constructor constructor = personClass.getConstructor();

        //生成Person对象(无参)
        Person person = constructor.newInstance();
        System.out.println(person);

        //生成无参的对象可以直接用Class中的newInstance()方法
        
        Person person1 = personClass.newInstance();
        System.out.println(person1);
    }

    @Test
    public void testGetDeclaredConstructor() throws Exception {
        Class personClass = Person.class;
        Constructor constructor = personClass.getDeclaredConstructor(String.class, int.class, String.class);//该方法相对是构造方法被私有时使用
        constructor.setAccessible(true);
        Person person = constructor.newInstance("明瑞", 168, "eeje");
        System.out.println(person);
    }
}

3.获取成员方法们:

Method[] getMethods();

Method getMethod(String name,类…parameterTypes)

Method[] getDeclaredMethods();

Method getDeclaredMethod(String name,类…parameterTypers)

Method:方法对象

  • 执行方法:第一参数是方法对象,第二是参数就是方法中的参数

    Object invoke(Object obj,Object…args)

    …parameterTypes:为参数类型如:String.class

  • 获取方法名称:

    String getName:获取方法名称

package com.haikang.reflect;

import com.haikang.person.Person;
import org.junit.Test;

import java.lang.reflect.Method;

public class ReflectMethod {

    

    @Test
    public void test1() throws Exception {
        //获取Class对象
        Class aClass = Class.forName("com.haikang.person.Person");

        //获取方法对象: Method         getMethod(String name,类...parameterTypes)
        //方法无参形式
        Method eat = aClass.getMethod("eat");
        // public Object invoke(Object obj, Object... args)
        eat.invoke(new Person());
    }

    @Test
    public void test2() throws Exception {
        //获取Class对象
        Class aClass = Person.class;
//        Method[] methods = aClass.getMethods();
//        for (Method method:
//             methods) {
//            String name = aClass.getName();
//            System.out.println(name);
//            System.out.println(method);
//       }

        //获取方法对象: Method         getMethod(String name,类...parameterTypes)
        //方法有参形式

        Method add = aClass.getMethod("add", int.class, int.class);
        add.invoke(new Person(),8,8);
    }

    @Test
    public void test3() throws Exception {
        //获取Class对象
        Class aClass = Person.class;
        Method inti = aClass.getMethod("inti");
        inti.setAccessible(true);
        inti.invoke(new Person());
    }
}

4.获取类名:
String getName();

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/584691.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号