反射01 Class类的使用

1 Class类的使用

  1.1 扫盲知识点

    在Java的世界里,万事万物都是对象【PS: 类也是一个对象】。

    坑01:java语言中,静态成员、普通数据类型不是对象

    技巧01:普通的数据类型虽然不是对象,但是普通的数据类型都有对应的包装类来让其转化成一个对象

    技巧02:静态的成员是属于类的而不是属于对象的,所以静态的成员不是对象

    技巧03:所有的类都是java.lang.Class的实例对象【there is a class name Class:Class类的实例就是所有的实例对象所属的类】

  1.2 Class类实例的创建

    任何一个类都是Class类的实例对象,Class类的实例对象三种表示方式;

    类也是一个实例对象,Class类的实例对象,这个对象我们称为该类的类类型;

      例如:我们创建一个名为Foo的类,Foo类就是Class类的实例对象,假设Foo类对应的Class类的实例名为c1,那么我们就称c1Foo类的类类型

      总结:类类型就是Class类的一个实例,而且一个类只能有一个类类型,也就是所一个类只能和一个Class对应;虽然可以通过三种方式创建一个Class实例,但是针对一个类而言这三种方式创建得到的Class实例都是相等的,因为一个类的类类型只能和一个Class的实例对象。(即:一个类通过三种方式创建的类类型其实是一样的)

    技巧01:不同的类对应的类类型都不一样,同理,不同的类对应的Class类实例都不一样

    技巧02:同一个类只有一个类类型,同理,同一个类只和一个Class类实例对应;所以,同一个类通过不同方式创建的类类型都是一样的

    1.2.1 利用class创建

      任何一个类都默认拥有一个名为class的静态成员变量,该类可以利用class静态成员去创建该类的类实例。

        例如:创建了一个名为Foo的类,执行 Foo.class 就会创建一个 Class 的实例,我们把得到的Class实例命名为c1,这个c1就是Foo类对应的类类型

    1.2.2 利用实例对象创建

      如果已经得到了某个类的实例,那么可以调用这个实例的成员方法getClass去创建该实例所属类的类类型

        例如:创建了一个名为Foo的类,根据Foo创建了一个Foo的实例对象foo,我们可以利用foo去调用getClass来创建Class类的一个实例c2,这个c2就是foo所属类Foo的类类型

    1.2.3 利用Class类创建

      Class类有一个静态方法forName,Class类可以利用这个静态方法创建一个Class实例;forName方法的参数是一个类的全名

        例如:创建了一个类Foo,该类的全名为 demo06_reflect.case01_class.Foo ,那么就可以利 Class.forName("demo06_reflect.case01_class.Foo")

去创建一个Class类的实例c3,这个c3就是Foo类的类类型

package demo06_reflect.case01_class;

/**
 * @author 王杨帅
 * @create 2018-08-03 21:43
 * @desc Class的使用
 **/
public class Demo01_Class {

    public static void main(String[] args) {

        // 创建Foo类的一个实例foo, Foo是foo的实例类型,foo是Foo的一个实例
        Foo foo = new Foo();

        // Class实例创建01:利用静态成员calss创建
        Class c1 = Foo.class;

        // Class实例创建02:利用实例成员ngetClass创建
        Class c2 = foo.getClass();

//        因为一个类只和一个Class实例对应,所以结果为true
        System.out.println(c1 == c2);

        // Class实例创建03:利用Class类的静态成员forName创建
        try {
            Class c3 = Class.forName("demo06_reflect.case01_class.Foo");
            System.out.println(c1 == c3);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }


    }

}

class Foo {
    public String name = "warrio";
    public void pirnt() {
        System.out.println("foo");
    }
}
View Code

  1.3 Class类实例的作用

    可以利用Class类实例去创建对应类的实例

      例如:c1Foo类对应的Class实例(即:c1Foo类的类类型),那么可以调用c1的实例方法newInstance去创建一个Foo实例foo,此时Foo类就称为foo实例的实例类型

    技巧01:通过Class实例创建该实例对应类的实例是必须进行类型转换,因为Class实例创建出来的实例类型都是Object类型的;而且还必须进行异常处理

    技巧02:Class实例对应的类必须拥有无参构造器【PS: 有参构造器会覆盖默认的无参构造器】

package demo06_reflect.case01_class;

/**
 * @author 王杨帅
 * @create 2018-08-03 21:43
 * @desc Class的使用
 **/
public class Demo01_Class {

    public static void main(String[] args) {

        try {
            Foo foo = (Foo) Foo.class.newInstance();
            foo.print();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

    }

}

class Foo {
    public String name = "warrio";
    public void print() {
        System.out.println("foo");
    }

    public Foo() {
    }

    public Foo(String name) {
        this.name = name;
    }
}
View Code

  1.4 代码汇总

package demo06_reflect.case01_class;

/**
 * @author 王杨帅
 * @create 2018-08-03 21:43
 * @desc Class的使用
 **/
public class Demo01_Class {

    public static void main(String[] args) {

//        Foo实例的表示
        Foo f1 = new Foo();

//        Foo也是一个实例对象【Foo类是Class类的实例对象】

        /**
         * 任何一个类都是Class类的实例对象,Class类的实例对象有三种表示方式
         */
//        Class实例的表示01:任何一个类都有一个隐含的静态成员变量class
        Class c1 = Foo.class;

//        Class实例的表示02:任何一个实例对象通过getClass方法就可以创建出一个Class类的实例
        Class c2 = f1.getClass();

        /**
         * c1 c2 表示了Foo类的类类型(class type)
         *      类也是一个实例对象,是Class类的实例对象;这个对象我们成为该类的类类型
         *      【类类型就是Class类的一个实例对象,而且一个类类型只能和一个Class的实例对应】
         */

//        c1 和 c2 都代表了Foo类的类类型,一个类只可能是Class类的一个实例对象
        System.out.println(c1 == c2);

//        Class实例的表示03:直接利用 Class 类的 forName 静态方法实现
        try {
            Class c3 = Class.forName("demo06_reflect.case01_class.Foo");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

//        04 可以利用该类的类类型创建该类的对象【通过c1/c2/c3创建Foo的实例】
//                前提:Foo类必须拥有无参数的构造方法
        try {
            Foo f2 = (Foo) c2.newInstance();
            f2.print();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

        Class c = Foo2.class;
        System.out.println(c1 == c);

    }

}

class Foo {
    void print(){
        System.out.println("foo");
    }
}

class Foo2 {}
View Code

猜你喜欢

转载自www.cnblogs.com/NeverCtrl-C/p/9416850.html
今日推荐