• 反射机制
    • 通过反射机制,可以操作字节码文件.
      可以读和修改字节码文件(class文件)
    • java.lang.reflect
    • 相关类有哪些
      • java.lang.Class — 代表字节码文件
      • java.lang.reflect.Method —代表字节码中的方法字节码
      • java.lang.reflect.Contructor —代表字节码中的构造方法字节码
      • java.lang.reflect.Filed — 代表字节码中的属性字节码

获取class的三种方式

  1. //Class.forName
  2. Class<?> c1 = Class.forName("java.lang.String");//代表String.class文件,或者c1代表String类型
  3. //java中任何一个对象都有一个getClass()
  4. String s = "abc";
  5. Class<? extends String> aClass = s.getClass();//s代表String
  6. Class y = String.class;

获取到Class能干什么?
通过Class的newInstance()方法来实例化对象
注意:newInstance()方法内部实际上调用了无参构造方法,必须保证无参构造存在才可以

  1. //通过反射机制获取class,通过class实例化对象
  2. Class<?> c = Class.forName("reflect.bean.User");
  3. Object obj = c.newInstance();//通过class实例化对象
  4. newInstance调用的无参构造方法

**

  1. Properties properties = new Properties();
  2. FileReader fileReader = new FileReader("src/main/java/reflect/classinfo.properties");
  3. properties.load(fileReader);
  4. fileReader.close();
  5. String className = properties.getProperty("className");
  6. Class<?> aClass = Class.forName(className);
  7. Object o = aClass.newInstance();
  8. System.out.println(o);

Class.forName()方法执行的时候发生了什么

  1. /*
  2. Class.ForName()发生了什么
  3. */
  4. public class ReflectTest04 {
  5. public static void main(String[] args) {
  6. try {
  7. // Class.forName()这个方法的执行会导致 类加载,所以会执行静态代码块.
  8. //如果你只想执行某个类的静态代码块,可以用Class.forName()
  9. Class.forName("reflect.MyClass");
  10. } catch (ClassNotFoundException e) {
  11. e.printStackTrace();
  12. }
  13. }
  14. }
  15. class MyClass {
  16. static {
  17. System.out.println("MyClass类的静态代码块执行了!");
  18. }
  19. }

AboutPath

  1. package reflect;
  2. import java.io.FileReader;
  3. import java.util.Properties;
  4. public class IOPropertiesTest {
  5. public static void main(String[] args) throws Exception {
  6. Properties properties = new Properties();
  7. String path = Thread.currentThread().getContextClassLoader().getResource("classinfo.properties").getPath();
  8. FileReader fileReader = new FileReader(path);
  9. properties.load(fileReader);
  10. String className = properties.getProperty("className");
  11. System.out.println(className);
  12. fileReader.close();
  13. }
  14. }

关于JDK中自带的类加载器

专门加载类的命令/工机具

  • JDK自带3个类加载器
    • 启动类加载器
    • 扩展类加载器
    • 应用类加载器

      反射获取Field

      ```java

public class Student {

//4个Field,分别采用了不同的权限修饰符
public int no; //Field对象
private  String name;
protected int age;
boolean sex;
public static final int num =10;

}

public class ReflectTest05 { public static void main(String[] args) throws Exception {

    Class<?> studentClass = Class.forName("bean.Student");
    //获取类中所有修饰符public的Filed
    Field[] fields = studentClass.getFields();

    //获取类中的所有属性(Field)
    Field[] declaredFields = studentClass.getDeclaredFields();
    for (Field declaredField : declaredFields) {
        //获取属性的名字
        System.out.println(declaredField.getName());

        //获取属性的类型
        Class<?> type = declaredField.getType();
        Type genericType = declaredField.getGenericType();
        System.out.println(genericType.getTypeName());


        //获取修饰符
        //返回的修饰符是个数字,每一个数字都是修饰符的代号!!!
        int modifiers = declaredField.getModifiers();
        String s = Modifier.toString(modifiers);
        System.out.println(modifiers+"  "+ s);
    }


}

}

no int 1 public

name java.lang.String 2 private

age int 4 protected

sex boolean 0

num int 25 public static final

<a name="n9Puf"></a>
### 反编译Field
```java
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class ReflectTest06 {
    public static void main(String[] args) throws Exception {
        StringBuilder s = new StringBuilder();
        Class<?> aClass = Class.forName("bean.Student");
        s.append(Modifier.toString(aClass.getModifiers()) +" class "+aClass.getSimpleName()+ " { \n");
        Field[] fields = aClass.getDeclaredFields();
        for (Field field : fields) {
            s.append("\t");
            s.append(Modifier.toString(field.getModifiers()));
            s.append(" ");
            s.append(field.getType().getSimpleName());
            s.append(" ");
            s.append(field.getName());
            s.append(";\n");
        }

        s.append("}");
        System.out.println(s);
    }
}
OUT:
public class Student { 
    public int no;
    private String name;
    protected int age;
     boolean sex;
    public static final int num;
}

获取Field的值,set,get

import java.lang.reflect.Field;
public class ReflectTest07 {
    //怎样通过java反射机制访问一个java对象的属性
        //给属性赋值set
        //获取属性的值get
    public static void main(String[] args) throws Exception {

        Class<?> clazz = Class.forName("bean.Student");
        Object o = clazz.getDeclaredConstructor().newInstance();
        Field name = clazz.getDeclaredField("name");

        name.setAccessible(true);

        name.set(o,"张舰方");

        System.out.println(name.get(o));


    }
}

可变长参数

class 可变长参数{
    public static void main(String[] args) {
        m(1,2,3);
    }

    private static void m(int... args) {
        Stream<Integer> boxed = Arrays.stream(args).boxed();
        Iterator<Integer> iterator = boxed.iterator();
        while (iterator.hasNext()){
            Integer next = iterator.next();
            System.out.println(next);
        }

        OptionalDouble average = Arrays.stream(args).average();
        System.out.println(average.toString());
        int[] ints = Arrays.stream(args).toArray();
        System.out.println(Arrays.toString(ints));
    }
}

反射方法

获取方法中的各种···

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;


public class ReflectTest08 {
    public static void main(String[] args) throws  Exception {
        //反射获取方法
        Class<?> userServiceClass = Class.forName("bean.UserService");
        Method[] declaredMethods =
                userServiceClass.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            //获取方法名字
            System.out.println(declaredMethod.getName());

            //获取返回值类型
//            System.out.println(declaredMethod.getGenericReturnType());
            Class<?> returnType = declaredMethod.getReturnType();
            System.out.println(returnType.getSimpleName());

            //获取修饰符
            System.out.println(Modifier.toString(declaredMethod.getModifiers()));

            //获取方法的参数列表
            Class<?>[] parameterTypes = declaredMethod.getParameterTypes();
            for (Class<?> parameterType : parameterTypes) {
                System.out.println(parameterType.getSimpleName());

            }
        }
    }
}

反射机制调用方法

import java.lang.reflect.Method;

public class ReflectTest09 {
    public static void main(String[] args) throws  Exception {
        //反射获取方法
        Class<?> userServiceClass = Class.forName("bean.UserService");
        //通过反射机制调用方法。
        Object o = userServiceClass.newInstance();

        Method[] declaredMethods = userServiceClass.getDeclaredMethods();
        Method method = declaredMethods[0];
        method.invoke(o,"zhangjianfnag","123456");
    }
}

反射机制调用构造方法

import java.lang.reflect.Constructor;
/*
反射机制调用构造方法
 */
public class ReflectTest12 {
    public static void main(String[] args) throws Exception {

        Class<?> clazz = Class.forName("bean.Vip");
        //调用无参构造方法
        Object o = clazz.newInstance();
        System.out.println(o);
        //调用有参构造方法
        Constructor<?> declaredConstructor = clazz.getDeclaredConstructor(int.class, String.class, String.class);
        Object obj1 = declaredConstructor.newInstance(11, "zhang", "2001-02");
        System.out.println(obj1);
    }
}

Vip{no=0, name='null', birth='null', sex=false}
Vip{no=11, name='zhang', birth='2001-02', sex=false}

反射机制获取父类和实现的接口

/*
反射机制调用构造方法
 */
public class ReflectTest13 {
    public static void main(String[] args) throws Exception {

        Class<?> stringClass = Class.forName("java.lang.String");

        //获取父类
        Class<?> superclass = stringClass.getSuperclass();
        System.out.println(superclass.getSimpleName());


        //获取接口
        Class<?>[] interfaces = stringClass.getInterfaces();
        for (Class<?> anInterface : interfaces) {
            System.out.println(anInterface);
        }
    }
}