反射机制
- 通过反射机制,可以操作字节码文件(读和改)。
- 在java.lang.reflect包下。
- Class:整个这个class文件
- Construcrot:字节码文件中的构造方法
- Method:字节文件中的方法
- Field:字节码文件中的属性
- 获取class文件第一:Class c=Class.forName(“java.lang.String”);这个方法是一个静态方法,参数是一个字符串,字符串需要是一个完整的类名。完整类名必须带有包名。
- 获取class文件第二:String s=“abc”;Class x=s.getClass();这个方法返回了一个class文件,就是String.calss文件。
- 获取class文件第三:java语言中的任何一种类型都有class属性;Class z=String.class。
- 当拿到一个Class类的一个引用c后,可以调用这个引用的newInstance方法,返回的是一个Object类,完成对象的创建,底层是调用了c这个类的无参构造方法,实际上创建的对象还是属于c这个类。这样也是创建对象。
- 如果只是希望某一个类的静态代码快执行,不希望其他程序执行,可以采用Class.foName(“java.reflect.MyClass”)的方式,这个方法的执行会导致类加载,而静态代码块只有在类加载的时候才会执行。
- src文件下的就叫类路径。
- 当类和文件都在src路径下的时候,要获取这个文件的绝对路径:String path =Thread.currentThread().getContextClassLoader().getResource(“className.properties”).getPath();此时这个path就是这个文件的绝对路径。
- 或者直接可以以流的形式返回 FileReader reader=Thread.currentThread().getContextClassLoader().getResourceAsStream(“classname.properties”);
- java.util包下提供了一个资源绑定器,遍与获取属性配置文件中的内容,这个时候文件必须放到类路径下。只能绑定.properties的文件。ResourceBundle bundle=ResourceBundle.getBundle(“className”); String className=bundle.getString(“key”);
- 获取类中的所有属性(field);先把这个类拿到,然后调用这个类中的getfields()方法,返回的是一个数组,而且这个方法只能拿到public的属性。或者调用这个类中的getDeclaredFields()方法,拿到所有的属性。然后想拿属性的名字就调用getName()方法。
- 拿到一个类后也可以得出它的类名:getName()方法得到是完整的类名,getSimpleName()拿到的是简类名。
- 拿到这个属性后也可以拿到这个属性的类型,调用getType()方法,返回的是一个class类型,然后用这个class类型的值去调用getName就可以拿到这个属性的类型。
- 也可以拿到这个属性的修饰符列表,getModifiers(),因为修饰符列表可以是多个,所以是s。返回的是一个int类型的,每一个修饰符列表所对应的数字是不同的,可以用Modifier类中的静态方法toString()方法区转换成这个修饰符列表,返回的是一个String。参数是所对应的int。
- 反射机制具有很强的通用性。
- 获取父类,获取当前类之后调用getSuperclass()方法。
- 获取接口,返回的是一个数组Class[] interfaces,那个类调用getInterfaces()方法。
类加载器
- 专门负责加载类的命令/工具。
- 代码在开始执行之前,会将所需要的类全部加载到jvm当中,通过类加载器加载。
- 启动类加载器专门加载:c:\java\jdk 1.8.0\jre\lib\rt.jar中的class文件,这里面都是jdk中最核心的类库。
- 如果通过启动类加载器加载不到的类的时候,会通过扩展类加载器加载。扩展类加载器专门加载:c:\java\jdk 1.8.0\jre\lib\ext*.jar中的class文件。
- 如果扩展类加载器也没有找到,那么应用类加载器会进行加载,应用类加载器专门加载:classpath中的jar包。环境变量。
- 双亲委派:启动类是父,拓展类是母,只有父和母都加载不到的时候,才会去应用类加载器里面加载。
可变长度参数
- 类型后面加三个点加名字。
- 也就是参数可以无限长。只能出现一个,而且出现在最后一个。
- 其实相当于一个数组。有length属性。
注解
- Annotation是一个引用数据类型,编译之后也生成.class文件。
- 修饰符列表 @interface 注释类型名{ };
- 注释的使用:@注释名
- @Override这个注解只能注解方法,而且必须是重写父类的方法,在编译阶段时检测的。
- @Target注解用来标注注解类型,标记那个注解只能出现在哪些位置上,例如方法,类等。称为元注解。
- @Retention注解用来标注注解类型,用来标记那个注解最终保存在哪里。source表示保存在java源文件中,class表示保存在class文件中,runtime标志保存在class文件中并且可以被反射机制所读取。
- @Deprecated表示注解某个方法或类已经过时了。
- 注解中可以定义属性,但是有属性的注解不能直接调用,必须@Deprecated (属性名=值)。或者在属性后面加一个default 后面加了默认值。
- 如果一个注解的只有一个属性而且属性名叫value的话,给它赋值的时候属性名可以不写直接赋值。
10.如果注解中的属性是一个数组,而且给它赋值的时候数组里面只有一个元素,那么大括号可以省略。