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,那么我们就称c1是Foo类的类类型
总结:类类型就是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"); } }
1.3 Class类实例的作用
可以利用Class类实例去创建对应类的实例
例如:c1是Foo类对应的Class实例(即:c1是Foo类的类类型),那么可以调用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; } }
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 {}