day43-反射02( 三 )

4.哪些类有Class对象

  1. 外部类,成员内部类,静态内部类,局部内部类,匿名内部类
  2. interface:接口
  3. 数组
  4. enum:枚举
  5. annotation:注解
  6. 基本数据类型
  7. void
例子:
package li.reflection.class_;import java.io.Serializable;//演示哪些类有Class对象public class allTypeClass {public static void main(String[] args) {Class<String> cls1 = String.class;//外部类Class<Serializable> cls2 = Serializable.class;//接口Class<Integer[]> cls3 = Integer[].class;//数组Class<float[][]> cls4 = float[][].class;//二维数组Class<Deprecated> cls5 = Deprecated.class;//注解//Thread类中的枚举State--用来表示线程状态Class<Thread.State> cls6 = Thread.State.class;//枚举Class<Long> cls7 = long.class;//基本数据类型Class<Void> cls8 = void.class;//void类型Class<Class> cls9 = Class.class;//Class类也有System.out.println(cls1);//class java.lang.StringSystem.out.println(cls2);//interface java.io.SerializableSystem.out.println(cls3);//class [Ljava.lang.Integer;System.out.println(cls4);//class [[FSystem.out.println(cls5);//interface java.lang.DeprecatedSystem.out.println(cls6);//class java.lang.Thread$StateSystem.out.println(cls7);//longSystem.out.println(cls8);//voidSystem.out.println(cls9);//class java.lang.Class}}5.类加载
day43-反射02

文章插图
  • 基本说明:
    反射机制是java实现动态语言的关键,也就是通过反射实现类动态加载
    1. 静态加载:编译时加载相关的类,如果没有则报错,依赖性太强
      静态加载的类,即使没有用到也会加载,并且进行语法的校验
    2. 动态加载:运行时加载相关的类,如果运行时不用该类,即使不存在该类,也不会报错,降低了依赖性
  • 类加载的时机:
    1. 当创建对象时(new)//静态加载
    2. 当子类被加载时 //静态加载
    3. 调用类中的静态成员时 //静态加载
    4. 通过反射 //动态加载
例子:静态加载和动态加载
import java.lang.reflect.*;import java.util.*;public class classLoad_ {public static void main(String[] args) throws Exception {Scanner scanner = new Scanner(System.in);System.out.println("请输入key");String key = scanner.next();switch (key) {case "1":Dog dog = new Dog();//静态加载,依赖性很强dog.cry();break;case "2"://反射 -->动态加载Class cls = Class.forName("Person"); //加载Person[动态加载]Object o = cls.newInstance();Method m = cls.getMethod("hi");m.invoke(o);System.out.println("ok");break;default:System.out.println("do nothing...");}}}//因为new Dog()是静态加载,因此必须编写Dog//Person类是动态加载,所以即使没有编写Person类也不会报错,只有当动态加载该类时,(有问题)才会报错class Dog{public void cry(){System.out.println("小狗在哭泣..");}}在没有编写Dog类时,即使在switch选择中,不一定会运行到new dog对象的case1,但是程序仍然报错了,因为静态加载的类,即使没有用到,也会加载,并且进行语法的校验
day43-反射02

文章插图
在编写了Dog类对象后,可以看到编译通过:
day43-反射02

文章插图
运行程序:可以看到,即使没有编写Person类,但是运行时没有用到,就不会报错
day43-反射02

文章插图
使用到Person类,报错:(运行时加载)
day43-反射02

文章插图
6.类的加载过程

经验总结扩展阅读