反射

1,反射机制有什么用?

  通过java语言中的反射机制可以操作字节码文件。有点类似于黑客。(可以读和修改字节码文件)。通过反射机制可以操作代码片段(class文件)

2,反射机制的相关类在哪个包下?

  java.lang.reflect.*.

3, 反射机制相关重要的类有哪些?

  java.lang.Class:                         代表整个字节码,代表一个类。

  java.lang.reflect.Mathod:           代表字节码中的方法字节码。

  java.lang.reflect.Constructor:    代表字节码中的构造方法字节码。

  java.lang.reflect.Field:               代表字节码中属性字节码。

  要操作一个类的字节码,需要首先获取到这个类的字节码,怎么获取?

  java.lang.Class实例?  三种方法

  1)Class  c = Class.forName("完整类名带包名");

  2)  Class c  = 对象.getClass();

  3)  Class  c = 任何类型.class();

  什么叫类路径下?放在src下的都是类路径下。src是类的根路径

  String paht = Thread.currentThread().getContextClassLoader().getResource("").getPath();  采用这个代码可以得到绝对路径。

  Thread.currentThread() ;当前线程对象。

  getContextClassLoader();是线程对象的方法,可以获得当前的类加载器对象。

  getResource(); [获取资源]这是类加载器对象的方法,当前线程的类加载器默认从类的根路径下加载资源。

 

  资源绑定器在java.util包下,便于获取属性配置文件中的内容。使用以下这种方式的时候,属性配置文件xxx.properties必须放在类路径下。

  ResourceBudle budle = ResourceBudle.getBundle("classinfo");

  System.out.println(budle.getString("className");

4, 类加载器

  1)什么是类加载器?

    专门负责加载类的命令/工具。   classLoader  

  2),JDK中自带的3个类加载器。

    1》启动类加载器     2》扩展类加载器    3》应用类加载器

  3),假设有这样一段代码: String  s = "abc';

    代码开始执行之前,会将所需要的类全部加载到JVM当中,通过类加载器,看到以上代码类加载器会找到String.class文件。

    怎么加载:

      首先通过”启动类加载器“加载   c:\program  Files \java\jdk1.8.0-101\jre\lib\rt.jar

      如果加载不到,会通过”扩展加载器“加载 :  c:\program  Files \java\jdk1.8.0-101\jre\lib\ext\*.jar

      如果还没有,会通过”应用加载器“加载   ,应用加载器专门加载: ClassPath中的类

 

public class Student {
    public String name ;
    public Integer age;

    public Student(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
//////////////////////////////////////////////////////////////////////////////////////////
//反射student类中所有的Field
public class Reflect01 { public static void main(String[] args) throws ClassNotFoundException { Class studentClass = Class.forName("com.atping.reflect_.Student"); Field[] fields = studentClass.getFields();//获取类中所有的属性 for (Field field : fields) { System.out.println(field.getName()); //遍历属性名字 name age Class<?> type = field.getType(); //获取属性的类型 System.out.println(type.getName()); } System.out.println("拿到全类名" + studentClass.getName()); System.out.println("类名" + studentClass.getSimpleName()); } }

 

 

5, 反射的注意事项

  使用反射机制,怎么去访问一个对象的属性。(set    get)

   Class studentClass = Class.forName("com.atping.student");  

    Object obj = studentClass.newInstance();   obj就是student对象

   获取no属性,根据属性的名称获取Field

   Field nofield = studentClass.getDeclaredField("no");

  nofield.set(obj,2022);                  // 给obj对象的no属性赋值2022

   sout(nofield.get(obj));         //打印出来

 

   反射机制让代码复杂了还是灵活了?

  可以访问私有属性吗?Field nameField = studentClass.getDeclaredField("name"); 打破封装

  nameField.setAccessible(true);

  nameField.set(obj,"jdbc:");

  sout(nameField.get(obj));  

 

public class StudentTest {
    /**
     * 传统方法  三要素: 要素1: 对象s
     *                 要素2: 属性age
     *                 要素3 : 赋值 tom
     * System.out.println(s.getName() + s.getAge());   
     * 读取属性 两要素: 1.获取s对象的age和name属性的值
     */
    @Test
    public void Test(){
        Student s = new Student();
        s.setAge(30);
        s.setName("tom");
        System.out.println(s.getName() + s.getAge());
    }
    @Test
    public void Test02() throws Exception {
        Class studentClass = Class.forName("com.atping.demo_.Student");
        Object obj = studentClass.newInstance();  //obj就是student对象
        Field noField = studentClass.getDeclaredField("age");
        noField.set(obj,28); //给obj对象的age属性赋值
        System.out.println(noField.get(obj));
        Field nameField = studentClass.getDeclaredField("name");
        nameField.setAccessible(true);
        nameField.set(obj,"jack");
        System.out.println(nameField.get(obj));
    }
}

 

posted @ 2022-12-30 17:14  阿文程序猿  阅读(31)  评论(0)    收藏  举报