美文网首页Java技术基础
java.lang.Class<T>类源码解读

java.lang.Class<T>类源码解读

作者: oneape15 | 来源:发表于2018-12-24 19:54 被阅读2次

    Class类是什么?

    Class是一个类,位于java.lang包下。在Java中每个类都有一个相对应的Class类的对象。
    也就是说,Java程序在启动运行一个 xxx.java类经过编译生成xxx.class文件后,就会在JVM虚拟机中产生一个xxx类对应的Class类的对象,用于表示这个xxx类的类型信息。
    PS Class类是反射中的核心类

    Class类中常用的方法

    获取类中的属性
    • getFields(): 获取类中public类型的属性
    • getField(String name): 获取类特定的方法,name参数指定了属性的名称
    • getDeclaredFields(): 获取类中所有的属性(public、protected、default、private),但不包括继承的属性。
    • getDeclaredField(String name): 获取类特定的方法,name参数指定了属性的名称
    获取类中的构造函数:
    • getConstructors():获取类中的公共方法
    • getConstructor(Class[] params): 获取类的特定构造方法,params参数指定构造方法的参数类型
    • getDeclaredConstructors(): 获取类中所有的构造方法(public、protected、default、private)
    • getDeclaredConstructor(Class[] params): 获取类的特定构造方法,params参数指定构造方法的参数类型
    获取类中的方法:
    • getMethods(): 获得类的public类型的方法
    • getMethod(String name, Class[] params): 获得类的特定方法,name参数指定方法的名字,params参数指定方法的参数类型
    • getDeclaredMethods(): 获取类中所有的方法(public、protected、default、private)
    • getDeclaredMethod(String name, Class[] params): 获得类的特定方法,name参数指定方法的名字,params参数指定方法的参数类型
    其它重要方法:
    • newInstance(): 通过类的不带参数 的构造方法创建这个类的一个对象
    • forName(String className): 获取className参数指定的类的class对象
    • forName(String className,boolean initialize,ClassLoader): 使用指定的类加载器获取className参数指定的类的class对象
    • getClassLoader(): 获取类加载器
    • getName(): 获取类名
    • getPackage(): 获取类所在的包名

    获取Class对象的三种方法

    1. 调用Class类的静态方法forName, 比如: Class.forName("java.lang.String")
    2. 使用类的.class语法, 比如:Class cls = String.class
    3. 调用对象的getClass方法, 比如:String str = "abc"; Class cls = str.getClass();

    直接撸代码

    各位能看到这里说明你是一个不一般的程序员;不好意思直接上代码了

    package com.oneape.unit;
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    
    /**
     * described :
     * Created by oneape on 2018-12-24 19:55.
     * Modify:
     */
    public class Person {
    
        private String name; // 姓名
        public  int    sex;  // 性别, 为了测试新建一个public的属性
    
        // 一个私有的构造方法
        private Person() {
        }
       // 一个公共的构造方法
        public Person(String name, int sex) {
            this.name = name;
            this.sex = sex;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getSex() {
            return sex;
        }
    
        public void setSex(int sex) {
        }
    
        public static void main(String[] args) throws Exception {
    
            Class clazz = Class.forName("com.oneape.unit.Person");
            Constructor[] constructors = clazz.getConstructors();
            System.out.println("1. 获取公共的构造方法数量为: " + constructors.length);
            Constructor[] allConstructors = clazz.getDeclaredConstructors();
            System.out.println("2. 获取所有的构造方法数量为: " + allConstructors.length);
    
            System.out.println("该类的所有公共字段属性列表如下:");
            Field[] fields = clazz.getFields();
            for (Field field : fields) {
                System.out.println(field.getType().toString() + " " + field.getName());
            }
    
            System.out.println("该类的所有字段属性列表如下:");
            Field[] allFields = clazz.getDeclaredFields();
            for (Field field : allFields) {
                System.out.println(field.getType().toString() + " " + field.getName());
            }
    
            System.out.println("----获取该类中所有的方法, 列表如下---");
            Method[] methods = clazz.getMethods();
            for (Method m : methods) {
                StringBuilder sb = new StringBuilder();
                sb.append(m.getName()).append("(");
                Class[] params = m.getParameterTypes();
                for (int i = 0; i < params.length; i++) {
                    sb.append(params[i].getName());
                }
                sb.append(")");
                System.out.println(sb.toString());
    
            }
            System.out.println("----获取该类中所有的方法, end---");
    
        }
    }
    
    

    直接运行结果如下:

    1. 获取公共的构造方法数量为: 1
    2. 获取所有的构造方法数量为: 2
    该类的所有公共字段属性列表如下:
    int sex
    该类的所有字段属性列表如下:
    class java.lang.String name
    int sex
    ----获取该类中所有的方法, 列表如下---
    main([Ljava.lang.String;)
    getName()
    setName(java.lang.String)
    setSex(int)
    getSex()
    wait(longint)
    wait(long)
    wait()
    equals(java.lang.Object)
    toString()
    hashCode()
    getClass()
    notify()
    notifyAll()
    ----获取该类中所有的方法, end---
    
    Process finished with exit code 0
    

    通过运行结果我们发现,获取的类中所有方法中,除了我们自己定义的方法这外,还出现了一些未定义的方法wait(longint), wait(long), wait(), equals(java.lang.Object), toString(),hashCode(),getClass(), notify(), notifyAll()这是什么原因????

    看过《JAVA编程思想》一书的老鸟一定会带着鄙视的眼神对你说:
    这不是所有对象都是java.lang.Object类的子对象么
    额~~~~~
    默默的打开jdk源代码又撸了Object类一次,源代码如下(注释已删除):

    package java.lang;
    public class Object {
    
        private static native void registerNatives();
        static {
            registerNatives();
        }
        public final native Class<?> getClass();
        public native int hashCode();
        public boolean equals(Object obj) {
            return (this == obj);
        }
        protected native Object clone() throws CloneNotSupportedException;
        public String toString() {
            return getClass().getName() + "@" + Integer.toHexString(hashCode());
        }
        public final native void notify();
        public final native void notifyAll();
        public final native void wait(long timeout) throws InterruptedException;
        public final void wait(long timeout, int nanos) throws InterruptedException {
            // 省略实现代码...
        }
        public final void wait() throws InterruptedException {
            wait(0);
        }
        protected void finalize() throws Throwable { }
    }
    

    好了,真相大白了~~

    相关文章

      网友评论

        本文标题:java.lang.Class<T>类源码解读

        本文链接:https://www.haomeiwen.com/subject/jaftlqtx.html