反射与新特性
1:反射(掌握)
(1)类的加载及类加载器
(2)反射:
通过字节码文件对象,去使用成员变量,构造方法,成员方法等类中的所有成分。
要想这样使用,首先你必须得到class文件对象,其实也就是得到Class类的对象。
Class类:
成员变量 Field
构造方法 Constructor
成员方法 Method
(3)反射的使用
1:通过反射获取构造方法并使用
// 获取字节码文件对象
Class c = Class.forName("day27_reflect.Person");
public Constructor[] getConstructors():所有公共构造方法
public Constructor[] getDeclaredConstructors():所有构造方法
获取单个构造方法
// public Constructor<T> getConstructor(Class<?>... parameterTypes)
// 参数表示的是:你要获取的构造方法的构造参数个数及数据类型的class字节码文件对象
Constructor con = c.getConstructor();// 返回的是构造方法对象
Person p = new Person();
System.out.println(p);
// public T newInstance(Object... initargs)
// 使用此 Constructor 对象表示的构造方法来创建该构造方法的声明类的新实例,并用指定
//初始化参数初始化该实例。
Object obj = con.newInstance();
2:通过反射获取成员变量并使用
// 获取字节码文件对象
Class c = Class.forName("cn.itcast_01.Person");
// 获取所有的成员变量
Field[] fields = c.getFields();
Field[] fields = c.getDeclaredFields();
for (Field field : fields) {
System.out.println(field);
}
/*
* Person p = new Person(); p.address = "北京"; System.out.println(p);
*/
// 通过无参构造方法创建对象
Constructor con = c.getConstructor();
Object obj = con.newInstance();
System.out.println(obj);
// 获取单个的成员变量
// 获取address并对其赋值
Field addressField = c.getField("address");
// public void set(Object obj,Object value)
// 将指定对象变量上此 Field 对象表示的字段设置为指定的新值。
addressField.set(obj, "北京");
// 给obj对象的addressField字段设置值为"北京"
// 获取name并对其赋值
// NoSuchFieldException
Field nameField = c.getDeclaredField("name");
// IllegalAccessException
nameField.setAccessible(true);
//设置为true表示可以获取私有
3:通过反射获取成员方法并使用
// 获取字节码文件对象
Class c = Class.forName("cn.itcast_01.Person");
// 获取所有的方法
// Method[] methods = c.getMethods(); // 获取自己的包括父亲的公共方法
// Method[] methods = c.getDeclaredMethods(); // 获取自己的所有的方法
// for (Method method : methods) {
// System.out.println(method);
// }
Constructor con = c.getConstructor();
Object obj = con.newInstance();
/*
* Person p = new Person(); p.show();
*/
// 获取单个方法并使用
// public void show()
// public Method getMethod(String name,Class<?>... parameterTypes)
// 第一个参数表示的方法名,第二个参数表示的是方法的参数的class类型
Method m1 = c.getMethod("show");
// obj.m1(); // 错误
// public Object invoke(Object obj,Object... args)
// 返回值是Object接收,第一个参数表示对象是谁,第二参数表示调用该方法的实际参数
m1.invoke(obj); // 调用obj对象的m1方法
// public void method(String s)
Method m2 = c.getMethod("method", String.class);
m2.invoke(obj, "hello");
System.out.println("----------");
// public String getString(String s, int i)
Method m3 = c.getMethod("getString", String.class, int.class);
Object objString = m3.invoke(obj, "hello", 100);
System.out.println(objString);
// String s = (String)m3.invoke(obj, "hello",100);
System.out.println("----------");
// private void function()
Method m4 = c.getDeclaredMethod("function");
m4.setAccessible(true);
m4.invoke(obj);
(4)反射案例
- 1:通过反射运行配置文件的内容
- 2:通过反射越过泛型检查
- 3:通过反射给任意的一个对象的任意的属性赋值为指定的值
(5)动态代理
2:JDK新特性
(1)JDK5(掌握)
- 装箱和拆箱
- 泛型
- 增强for
- 静态导入
- 可变参数
- 枚举
(2)JDK6(了解)
(3)JDK7(理解)
1.二进制字面量 int x = 0b100101;
2。数字字面量可以出现下划线 int y = 1_1123_1000;
3.switch语句可是用字符串
4.泛型推断(泛型简化) ArrayList<String> array = new ArrayList<>();
5.多catch的使用
6.try-with-resources 语句
try(必须是java.lang.AutoCloseable的子类对象){…}
try (FileReader fr = new FileReader("a.txt");
FileWriter fw = new FileWriter("b.txt");) {
int ch = 0;
while ((ch = fr.read()) != -1) {
fw.write(ch);
}
} catch (IOException e) {
e.printStackTrace();
}
//无需close()方法