反射以及对Class类的理解

导读:本篇文章讲解 反射以及对Class类的理解,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

目录

对于反射的理解

反射机制能提供的功能

反射前后的操作对比

首先是Person类

反射之前,对于Person类的操作

 反射之后,对于Person类的操作

 反射可能出现的问题:

关于java.lang.Class类的理解

获取Class的实例的方式

方式一:调用运行时类的属性(泛型):.class

方式二:通过运行时类的对象,调用getClass()

方式三: 调用Class的静态方法:forName(String classPath)

方式四:使用类的加载器:ClassLoader  (了解)

对于反射的理解

        Reflection(反射)是被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法。

        框架 = 反射 + 注解 + 设计模式。

反射机制能提供的功能

反射以及对Class类的理解

反射前后的操作对比

首先是Person类

public class Person {

    private String name;
    public int age;

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    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 Person(String name, int age) {

        this.name = name;
        this.age = age;
    }

    private Person(String name) {//权限为private私有
        this.name = name;
    }

    public Person() {
        System.out.println("Person()");
    }

    public void show(){
        System.out.println("你好,我是一个人");
    }

    private String showNation(String nation){
        System.out.println("我的国籍是:" + nation);
        return nation;
    }
}

反射之前,对于Person类的操作

    public void test1() {

        //1.创建Person类的对象
        Person p1 = new Person("Tom", 12);

        //2.通过对象,调用其内部的属性、方法
        p1.age = 10;
        System.out.println(p1.toString());

        p1.show();

        //在Person类外部,不可以通过Person类的对象调用其内部私有结构。
        //比如:name、showNation()以及私有的构造器
    }

Person{name=’Tom’, age=10}
你好,我是一个人

 反射之后,对于Person类的操作

public void test2() throws Exception{

    Class clazz = Person.class;
    //1.通过反射,创建Person类的对象
    Constructor cons = clazz.getConstructor(String.class,int.class);
    Object obj = cons.newInstance("Tom", 12);
    Person p = (Person) obj;
    System.out.println(p.toString());
    //2.通过反射,调用对象指定的属性、方法
    //调用属性
    Field age = clazz.getDeclaredField("age");
    age.set(p,10);
    System.out.println(p.toString());

    //调用方法
    Method show = clazz.getDeclaredMethod("show");
    show.invoke(p);

    System.out.println("*******************************");

    //通过反射,可以调用Person类的私有结构的。比如:私有的构造器、方法、属性
    //调用私有的构造器
    Constructor cons1 = clazz.getDeclaredConstructor(String.class);
    cons1.setAccessible(true);
    Person p1 = (Person) cons1.newInstance("Jerry");
    System.out.println(p1);

    //调用私有的属性
    Field name = clazz.getDeclaredField("name");
    name.setAccessible(true);
    name.set(p1,"HanMeimei");
    System.out.println(p1);

    //调用私有的方法
    Method showNation = clazz.getDeclaredMethod("showNation", String.class);
    showNation.setAccessible(true);
    String nation = (String) showNation.invoke(p1,"中国");//相当于String nation = p1.showNation("中国")
    System.out.println(nation);

}

Person{name=’Tom’, age=12}
Person{name=’Tom’, age=10}
你好,我是一个人
*******************************
Person{name=’Jerry’, age=0}
Person{name=’HanMeimei’, age=0}
我的国籍是:中国
中国

 反射可能出现的问题:

1.通过new的方式或反射的方式都可以调用公共的结构,开发中到底用哪个?

     直接用new的方式。

2.什么时候会用反射的方式?(反射的主要特征是动态性)

3.反射机制与面向对象中的封装性并不矛盾。

关于java.lang.Class类的理解

1.类的加载过程:程序经过javac.exe命令之后,会生成一个或多个字节码文件(.class结尾)。之后我们使用java.exe命令对某个字节码文件进行解释运行,相当于将某个字节码文件加载到内存中。加载到内存中的类,我们将其称为运行时类(Class的一个实例)。

2.加载到内存中的运行时类,会缓存一定的时间。在此时间之内,我们可以通过不同的方式来获取运行时类。

获取Class的实例的方式

方式一:调用运行时类的属性(泛型):.class

Class<Person> clazz1 = Person.class;//泛型
System.out.println(clazz1);

class com.atguigu.java.Person

方式二:通过运行时类的对象,调用getClass()

Person p1 = new Person();
Class clazz2 = p1.getClass();//获取一下对象是哪个类造的
System.out.println(clazz2);

Person()
class com.atguigu.java.Person

方式三: 调用Class的静态方法:forName(String classPath)

Class clazz3 = Class.forName("com.atguigu.java.Person");//去寻找这个路径下的这个类,运行之后可以判断是否正确
//   clazz3 = Class.forName("java.lang.String");

System.out.println(clazz3);//class com.atguigu.java.Person

方式四:使用类的加载器:ClassLoader  (了解)

ClassLoader classLoader = ReflectionTest.class.getClassLoader();//加载到内存中的类,运行时类
Class clazz4 = classLoader.loadClass("com.atguigu.java.Person");
System.out.println(clazz4);//class com.atguigu.java.Person

Class实例是哪些结构的说明;

int[] a = new int[10];
int[] b = new int[100];
Class c10 = a.getClass();
Class c11 = b.getClass();
// 只要数组的元素类型与维度一样,就是同一个Class
//一维数组,整数类型的元素
System.out.println(c10 == c11);//true

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/83283.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!