反射与新特性

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()方法

 

 

posted @ 2018-06-11 09:06  要死要活的程序猿啊  阅读(148)  评论(0编辑  收藏  举报