首页 > 其他分享 >反射类

反射类

时间:2022-09-29 19:22:09浏览次数:43  
标签:反射 System Class Person println class out

反射类

一,关于java.lang.Class类的理解

关于java.lang.Class类的理解
1.类的加载过程:
程序经过javac.exe命令以后,会生成一个或多个字节码文件(.class结尾)。
接着我们使用java.exe命令对某个字节码文件进行解释运行。相当于将某个字节码文件
加载到内存中。此过程就称为类的加载。加载到内存中的类,我们就称为运行时类,此
运行时类,就作为Class的一个实例。
2.换句话说,Class的实例就对应着一个运行时类。
3.加载到内存中的运行时类,会缓存一定的时间。在此时间之内,我们可以通过不同的方式
来获取此运行时类。

    //获取Class的实例的方式(前三种方式需要掌握)
    @Test
    public void test3() throws ClassNotFoundException {
        //方式一: 调用运行时类的属性:.class
        Class<Person> clazz1 = Person.class;
        System.out.println(clazz1);

        //方式二:通过运行时类的对象,调用getClass()
        Person p1 = new Person();
        Class clazz2 = p1.getClass();
        System.out.println(clazz2);

        //方式三:调用Class的静态方法:forName(String classPath)(常用)(运行时查找类的存在,体现动态性)
        Class clazz3 = Class.forName("com.atguigu.java.Person");
//        clazz3 = Class.forName("java.lang.String");
        System.out.println(clazz3);

        System.out.println(clazz1 == clazz2);//true
        System.out.println(clazz1 == clazz3);//true获取内存中的同一个运行时类

        //方式四:使用类的加载器:ClassLoader  (了解)
        ClassLoader classLoader = ReflectionTest.class.getClassLoader();
        Class clazz4 = classLoader.loadClass("com.atguigu.java.Person");
        System.out.println(clazz4);
        System.out.println(clazz1 == clazz4);
    }

    //Class实例可以是哪些结构的说明:
    @Test
    public void test4(){
        Class c1 = Object.class;
        Class c2 = Comparable.class;
        Class c3 = String[].class;
        Class c4 = int[][].class;
        Class c5 = ElementType.class;
        Class c6 = Override.class;
        Class c7 = int.class;
        Class c8 = void.class;
        Class c9 = Class.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);

    }
二,创建对象的反射前后对比
//反射之前

@Test
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的操作
@Test
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.getMethod("show");
    show.invoke(p);

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

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

    //调用私有的属性
    Field name = clazz.getDeclaredField("name");
    name.setAccessible(true);
    name.set(p1,"Hanmm");
    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);
}

疑问1:通过直接new的方式或反射的方式都可以调用公共的结构,开发中到底用那个?
建议:直接new的方式。
什么时候会使用:反射的方式。 反射的特征:动态性
疑问2:反射机制与面向对象中的封装性是不是矛盾的?如何看待两个技术?
不矛盾。

三,通过发射创建对应的运行时类的对象
@Test
public void test1() throws IllegalAccessException,InstantiationException {
    Class<Person> clazz = Person.class;
    /*
    newInstance():调用此方法,创建对应的运行时类的对象,内部调用了运行时类的空参的构造器。

    要想此方法正常的创建运行时类的对象,要求:
    1.运行时类必须提供空参的构造器
    2.空参的构造器的访问权限得够。通常,设置为public。


    在javabean中要求提供一个public的空参构造器。原因:
    1.便于通过反射,创建运行时类的对象
    2.便于子类继承此运行时类时,默认调用super()时,保证父类有此构造器

     */
    Person obj = clazz.newInstance();
    System.out.println(obj);
}

标签:反射,System,Class,Person,println,class,out
From: https://www.cnblogs.com/blwx/p/16742709.html

相关文章

  • 并发反射服务器
    #include<stdio.h>#include<stdlib.h>#include<sys/socket.h>#include<sys/wait.h>#include<netinet/in.h>#include<arpa/inet.h>#include<time.h>#include......
  • 反射快速入门
    创建Cat模型packagecom.reflection.domain;publicclassCat{privateStringname="小喵";publicvoidhi(){System.out.println("hi"+nam......
  • 反射、注解、动态代理的理解
    反射的核心就是拿到了.java编译后的.class文件。通过一系列的API,可以拿到该类中的成员:构造器、属性、方法等。注解,可以告诉编译器或者JVM做一些事情。比如说重写的@Overri......
  • 反射(类加载内存分析)
    java内存图:  类的加载过程: 加载:  将class文件字节码内容加载到内存中,并将这些静态数据转换成方法区的运行时数据结构,然后生成一个代表这个类的java.lang.Class对象链......
  • JavaWeb--Junit测试,反射(复习),注解
    JavaWeb--Junit测试,反射(复习),注解JavaWeb概述javaweb是使用java语言完成服务器程序的开发Junit单元测试黑盒测试:不需要写代码,给输入值,看程序是否能够输出期望的值......
  • 466Class对象功能_获取Constructor和467反射_Class对象功能_获取Method
    Class对象功能_获取ConstructorConstructor<?>[]getConstructors()Constructor<T>getConstructor(Class<?>...parameterTypes) Constructor<?>[]getDeclaredConst......
  • .Net 7内容汇总(3)--反射优化
    反射这玩意,一直以来都是慢的代名词。一说XXX系统大量的反射,好多人第一印象就是会慢。但是呢,我们又不得不使用反射来做一些事情,毕竟这玩意可以说啥都能干了对吧。It’simme......
  • JAVA 反射与模块化
    JAVA反射与模块化类加载类的初始化步骤假如类还未被加载和连接,则程序现在加载并连接该类假如该类的直接父类还未被初始化,则先初始化其直接父类假如类中有初始化语......
  • 反射_Class对象功能_获取Method
    反射_Class对象功能_获取Method获取Class对象的方式:  Person类......
  • 反射_Class对象功能_获取Field和反射_Class对象功能_获取Constructor
    反射_Class对象功能_获取Field反射_Class对象功能_获取ConstructorStudent类   pro.properties配置文件   ReflectTest类测试  想运行其他类中的方......