JAVA基础--Class反射的简单应用(1)

       咱们在编写JAVA程序的时候,建立一个对象JVM是怎样来找到,理解并编译到.class中的?那咱们就来看看在编译中Class对象的伟大魅力;好了,废话很少说,直接上干货:java

1: 首先,咱们来建立一个对象,方便咱们测试:数组

package entity;

/**
 *@description  TODO 测试对象
 *@date  2018年1月1日
 *@author  geYang
 **/
public class Person {
    /**
     * 姓名
     */
    private String name;
    /**
     * 年龄
     */
    private int age;
    /**
     * 住址
     */
    private String address;

    public Person() {
    }

    public Person(String name, int age, String address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }
    
    public static void printInfo(){
        System.out.println("静态方法调用");
    }
    
    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 String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + ", address=" + address + "]";
    }
    
    
}

2: 测试Class的用法:ide

package reflex;

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

/**
 *@description  TODO Class类对象的简单测试
 *@date  2018年1月1日
 *@author  geYang
 **/
public class ClassTest {
    /**
     * 运行时类型信息使得咱们能够在程序运行时发现和使用类型信息;而类型信息使咱们从只能在编译期执行面向类型的操做的禁锢中解脱出来;
     * 而且可使用某些很是强大的程序;
     * 
     * JAVA是如何让程序在运行时识别对象和类的信息的.主要有两种方法:
     * 1: "传统的" RTTI : 它假定咱们在编译时已经知道的须要的类型信息;
     * 2: "反    射" 机制         : 它容许咱们在运行时发现和使用类的信息;
     * 
     * 注: 运行时类型识别(RTTI, Run-Time Type Identification)是Java中很是有用的机制
     * ,在Java运行时,RTTI维护类的相关信息.多态(polymorphism)是基于RTTI实现的.RTTI的功能主要是由Class类实现的.
     * 
     * Class 对象:
     *    要理解RTTI在JAVA中的工做原理,首先必须知道类型信息在运行时时如何表示的,这项工做是由称为Class对象的特殊对像完成的;
     * 事实上Class对象就是用来建立类的所用的"常规"对象的.Java使用Class对象来执行其RTTI; 
     *    类是程序的一部分,每一个类都有一个Class对象.每当编写或编译一个新的类时都会产生一个新的对象(被保存在其.class文件中).
     * 为了生成这个类的对象,运行这个程序的JVM将被称为"类加载器"的子系统;
     *    全部的类都是在对其第一次使用时,动态的加载到JVM中的.当程序建立第一个对类的静态成员的引用时,就会加载这个类.这证实构造器也是类的静态方法;
     * 即便没有使用static,因此使用new操做符建立类的新对象也会被当作对类的静态成员的引用;
     *    所以Java程序在其开始运行以前,并不是是被彻底加载,其各个部分是在必须时才加载的;动态加载也是Java的一大特性;
     * 
     *    使用中类加载器首先检查这个类的Class对象是否已经被加载.若是还没有加载,默认的类加载器就会根据类名查找.class文件.这个类的字节码被加载时,
     * 它们会接受验证,以确保没有被破坏;一担某个类的Class被载入内存,它就会用来建立这个类的全部对象.
     * 
     * 下面就来测试Class的用法:
     * @throws ClassNotFoundException 
     * @throws SecurityException 
     * @throws NoSuchFieldException 
     * @throws NoSuchMethodException 
     * @throws InvocationTargetException 
     * @throws IllegalArgumentException 
     * @throws IllegalAccessException 
     * @throws InstantiationException 
     **/
    
    public static void main(String[] args) throws Exception {
        /* (举个例子啊) 假设咱们当前并不知道String类是干什么的,但咱们只知道有 "java.lang.String" 这个名字,那么怎么来获取String对象呢? */
        //Class<?> clazz = Class.forName("java.lang.String");
        //换成其余也同样
        Class<?> clazz = Class.forName("entity.Person");
        /* 要抛个找不到的错,打印一下=>结果:"class java.lang.String" (没有报错)证实有这个类*/
        System.out.println(clazz);
        
        /* 2,光有类也没用,我还想看看他下面有什么属性  */
        System.out.println("================= 全部属性  =====================");
        Field[] fields = clazz.getDeclaredFields();
        //获取到一个 Field 对象的数组(证实,类中的属性也都是一个对象),打印一下:
        for(Field field : fields){
            System.out.println(field);
        }
        System.out.println("================= 单一属性  =============");
        Field field = clazz.getDeclaredField("name");
        System.out.println(field);
        
        
        /* 3,获取类的方法  */
        System.out.println("================= 全部方法 =====================");
        Method[] methods = clazz.getDeclaredMethods();
        for(Method method : methods){
            System.out.println(method);
        }
        System.out.println("========= 单一方法(无参) =========");
        Method method = clazz.getDeclaredMethod("getName", new Class[]{});
        System.out.println(method);
        System.out.println("========= 单一方法(有参) =========");
        Method method2 = clazz.getDeclaredMethod("setName", new Class[]{String.class});
        System.out.println(method2);
        
        
        /* 3,获取类的构造器  */
        System.out.println("================= 全部构造器 =====================");
        Constructor<?>[] constructors = clazz.getDeclaredConstructors();
        for(Constructor<?> constructor : constructors){
            System.out.println(constructor);
        }
        System.out.println("======== 单一构造器(无参) =======");
        Constructor<?> constructor = clazz.getDeclaredConstructor(new Class[]{});
        System.out.println(constructor);
        System.out.println("======== 单一构造器(有参) =======");
        Constructor<?> constructor2 = clazz.getDeclaredConstructor(new Class[]{String.class,int.class,String.class});
        System.out.println(constructor2);
        
        /*4, 根据类的的构造器来获取对象*/
        System.out.println("================= 对象(无参) =====================");
        Object object = constructor.newInstance(new Object[]{});
        System.out.println(object);
        System.out.println("================= 对象(有参) =====================");
        Object object2 = constructor2.newInstance(new Object[]{"张三",18,"绵阳"});
        System.out.println(object2);
    }
    
}

作了上面的测试,那么对于Class对象已经有了初步的了解;测试

参考: https://ke.qq.com/course/180327flex

相关文章
相关标签/搜索