类加载器、反射

当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化。

加载:指将class文件读入内存,并为之创建一个class对象。

连接:验证  是否有正确的内部结构,并和其它类协调一致。准备  负责为类的静态成员分配内存,并设置默认初始化值。 解析  将类的二进制数据中的符号引用替换为直接引用。

初始化:初始化步骤。

Bootstrap ClassLoader 根类加载器

也被称为引导类加载器,负责Java核心类的加载

Extension ClassLoader 扩展类加载器

负责JRE的扩展目录中jar包的加载。

System ClassLoader 系统类加载器

负责在JVM启动时加载来自java命令的class文件,以及classpath环境变量所指定的jar包和类路径。

 

反射:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

Class类:

获取Class对象的三种方式:

 

public static void main(String[] args) throws ClassNotFoundException {
  //获取字节码文件对象
  //1.通过对象获取
  Class c1=new Person().getClass();
  System.out.println(c1);
  //2.通过类名获取
  Class c2=Person.class;
  System.out.println(c2);
  //System.out.println(c1==c2);//true
  //3.通过class类的静态方法获取
  Class c3=Class.forName("com.oracle.demo01.Person");
  System.out.println(c3);
}

Person类:

public class Person {
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }
    private String name;
    public int age;
    public Person(){
        System.out.println("public Person()");
    }
    public Person(String name){
        this.name=name;
        System.out.println("public Person(String name)");
    }
    private Person(int age){
        this.age=age;
        System.out.println("private Person(int age)");
    }
    static{
        System.out.println("静态代码块");
    }
    public void eat(){
        System.out.println("public void eat()");
    }
    public void sleep(String name,int age){
        System.out.println("public void sleep(String name,int age)");
    }
    public void sleep(String name){
        System.out.println("public void sleep(String name)");
    }
    private void smoke(int age){
        System.out.println("private void smoke(int age)");
    }
}

通过反射方式,获取构造方法,创建对象:

public static void method() throws ClassNotFoundException{
  //获取字节码文件对象
  Class c=Class.forName("com.oracle.demo01.Person");
  //获取所有公共的构造方法对象数组
  //Constructor[] cons=c.getConstructors();
  //获取所有构造方法
  Constructor[] cons=c.getDeclaredConstructors();
  for(Constructor con:cons){
    System.out.println(con);
  }
}

public static void method2() throws NoSuchMethodException, SecurityException, ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
  //获取字节码对象
  Class c=Class.forName("com.oracle.demo01.Person");
  //获取空参构造方法对象
  Constructor con=c.getConstructor();
  //调用构造方法创建对象
  Object obj=con.newInstance();
  //向下转型
  Person p=(Person)obj;
  p.eat();
}
public static void method3() throws NoSuchMethodException, SecurityException, ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
  //获取字节码对象
  Class c=Class.forName("com.oracle.demo01.Person");
  //获取有参构造方法对象
  Constructor con=c.getConstructor(String.class);
  //调用构造方法创建对象
  Object obj=con.newInstance("张三");
  //向下转型
  Person p=(Person)obj;
  p.eat();
}

通过反射方式,获取私有构造方法,创建对象:

public static void method4() throws NoSuchMethodException, SecurityException, ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
  //获取字节码对象
  Class c=Class.forName("com.oracle.demo01.Person");
  //获取有参构造方法对象
  Constructor con=c.getDeclaredConstructor(int.class);
  //暴力反射:取消java语言检测访问
  con.setAccessible(true);
  //调用构造方法创建对象
  Object obj=con.newInstance(18);
  //向下转型
  Person p=(Person)obj;
  p.eat();
}

通过反射,创建对象,获取指定的成员变量,进行赋值与获取值:

public static void method01() throws NoSuchFieldException, SecurityException, ClassNotFoundException, InstantiationException, IllegalAccessException{
  //获取字节码文件对象
  Class c=Class.forName("com.oracle.demo01.Person");
  //获取公共的成员变量
  Field f=c.getField("age");
  //快速创建对象
  Object obj=c.newInstance();
  //给对象的成员变量赋值
  f.set(obj, 18);
  System.out.println(obj);
}
public static void method02() throws NoSuchFieldException, SecurityException, ClassNotFoundException, InstantiationException, IllegalAccessException{
  //获取字节码文件对象
  Class c=Class.forName("com.oracle.demo01.Person");
  //获取公共的成员变量
  Field f=c.getDeclaredField("name");
  //暴力反射
  f.setAccessible(true);
  //快速创建对象
  Object obj=c.newInstance();
  //给对象的成员变量赋值
  f.set(obj, "你好");
  System.out.println(f);
}

通过反射获取成员方法并使用:

 

public static void main(String[] args) throws NoSuchMethodException, SecurityException, ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
  //获取字节码文件对象
  Class c=Class.forName("com.oracle.demo01.Person");
  //获取公共有参成员方法
  Method method=c.getMethod("sleep", String.class,int.class);
  //System.out.println(method);
  //快速创建对象
  Object obj=c.newInstance();
  //调用方法
  method.invoke(obj, "张三",18);
}

泛型擦除:

public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
  //泛型擦除
  ArrayList<String> arr=new ArrayList<String>();
  //反射
  Class c=arr.getClass();
  Method method=c.getMethod("add", Object.class);
  //调用
  method.invoke(arr, 123);
  System.out.println(arr);
}

 

posted on 2019-06-26 14:38  boss-H  阅读(236)  评论(0编辑  收藏  举报

导航