第89节:Java中的反射技术

作者: 魔王哪吒 | 来源:发表于2019-02-26 08:22 被阅读35次
    第89节:Java中的反射技术

    第89节:Java中的反射技术

    反射技术是动态的获取指定的类,和动态的调用类中的内容(没有类前就可以创建对象,将对象的动作完成,这就是动态的获取指定的类)。

    配置文件把具体实现的类名称定义到配置文件中。

    反射技术的作用可以提高程序的扩展性。

    Object

    clone() 用于创建并返回此对象的一个副本

    equals(Object obj) 用于指示其他某个对象是否与这个对象“相等”

    getClass() 用于返回此Object的运行时类

    hashCode() 用于返回该对象的哈希码值

    notify() 用于唤醒在此对象监视器上等待的单个线程

    notifyAll() 用于唤醒在此对象监视器上等待的单个线程

    notifyAll() 用于唤醒在此对象监视器上等待的所有线程

    toString() 用于返回该对象的字符串

    要获取某文件中的成员,就要先获取某文件的对象

    public class Person{
     private String name;
     private int age;
     public Person(){
      super();
     }
     public Person(String name, int age){
      super();
      this.name = name;
      this.age = age;
     }
    }
    
    // 定义一个方法获取对象
    public static void getClass(){
     Person p = new Person();
     Class class = p.getClass();
    }
    
    public static void getClass(){
     String className = "com.dashucoding.Person";
     Class cla = Class.forName(className);
     
     Object obj = cla.newInstance();
     // 获取创建字节码对象所表示的类的实例
     
    }
    
    pulic T newInstance() throws InstantiationException, IllegalAccessException
    创建此Class对象所表示的类的一个实例,对一个带有一个空参数列表的new表达式实例化这个类。
    

    获取构造函数

    public static void getConstructorDemo() throws Exception {
     String className = "com.dashucodiing.Person";
     Class cla = Class.forName(className);
    
     Constructor cons = cla.getConstructor(String.class, int.class);
     Object obj = cons.newInstance("dashu",12);
    }
    

    获取字段

    public static void getFieldDemo() throws Exception {
     String className = "com.dashucoding.Person";
     Class cla = Class.forName(className);
     
     String fieldName = "age";
     //获取字段
     Field field = cla.getField(fieldName);
     System.out.printlnn(field);
    }
    
    getField
    public Field getField(String name) thows NoSuchFieldException, SecurityException.
    返回一个Field对象。
    
    NoSuchFieldException
    如果没有找到带有指定名的字段会报这个错
    NullPointerException
    如果name为null会报这个错
    

    获取方法

    public static void getMethodDemo() throws Exception {
     String className = "com.dashucoding.Person";
     class cla = Class.forName(className);
     
     String methodName = "show";
      Method method = cla.getMethod( methodName, String.class,int.class);
     Object obj = cla.newInstance();
      method.invoke(obj, "dashu",12;
    }
    

    反射技术是这样的以前先有类,才new对象,现在有了它之后,先new对象,把创建对象的动作做完,接着才在配置文件中添加哪个类。

    当我们使用的类不明确时,通过配置文件告诉应用程序即可。

    File configFile = new File("tempfile\\dashu.properties");
    if(!configFile.exists()){
     configFile.createNewFile();
    }
    
    // 读取配置文件
    FileReader fr = new FileReader(configFile);
    // 为了获取其中的键值信息
    Properties prop = new Properties();
    prop.load(fr);
    for(int x = 1; x<=prop.size(); x++){
     String className = prop.getProperty("dashu"+x);
     Class cla = Class.forName(className);
     class.newInstance();
    }
    

    类加载的概述:

    如果某个类被这个程序使用时,如果这个类没有被加载到内存中,就会由系统通过加载,连接,初始化三个步骤实现这个类并对其进行初始化。

    加载是由内存进行class文件的读取,简单来说就是class文件读入内存中,接着创建一个Class对象,任何类被使用的时候,由系统建立一个Class对象。(class文件加载到内存中)

    连接:验证,准备,解析

    验证内部结构是否正确
    准备是否为类的静态成员分配内存,并设置默认的初始化值
    解析是将类的二进制数据中的符号引用换为直接引用哦

    初始化进行初始化的操作

    类加载器的概念

    类加载器是把.class文件加载到内存中,并生成对应的Class对象。

    类加载器的分类有哪些?

    Bootstrap ClassLoader 根类加载器
    Extension ClassLoader 扩展类加载器
    System ClassLoader 系统类加载器

    描述其作用:

    Bootstrap ClassLoader 根类加载器

    路径 jre/lib/rt.jar文件 核心类的加载
    

    Extension ClassLoader 扩展类加载器

    路径 jre/lib/ext目录 jar包的加载
    

    System ClassLoader 系统类加载器

    jvm启动时加载来自java命令的class文件
    

    反射

    源文件 -> 字节码 -> 创建对象
    
    Class cla = Class.forName("类名"); // 读取配置文件
    
    Class cla = Person.class
    
    Person p = new Person(); Class cla = p.getClass();
    

    三种方式:

    Class cla = Class.forName("com.dashucoding.Person");
    Class cla1 = Person.class;
    Person p = new Person();
    Class cla2 = p.getClass();
    System.out.println(cla = cla1);
    System.out.println(cla2 = cla1);
    

    Class.forName()读取配置文件

    public class Demo {
     public static void main(String[] args) throws Exception {
      Juicer j = new Juicer();
      j.run(new Apple());
     }
    
     class Apple {
      public void squeeze() {
       System.out.println();
      }
     } 
     class Juicer {
       public void run(Apple a) {
        a.squeeze();
       }
     }
    }
    
    interface Fruit {
     public void squeeze();
    }
    class Apple implements Fruit {
     public void squeeze(){
      System.out.println("");
     }
    }
    
    public static void main(String[] args) throws ClassNotFoundException {
     Class cla1 = Class.forName("com.dashucodiing.Person");
     Class cla2 = Person.class;
     Person p = new Person();
     Class cla3 = p.getClass();
    }
    

    通过反射获取带参构造方法

    package com.dashucoding.demo
    public class Demo {
     public static void main(String[] args) {
      Class clazz = Class.forName("com.dashucoding.bean.Person");
     // Person p = (Person) clazz.newInstance();
     Constructor c = clazz.getConstructor(String.class,int.class);
      Person p = (Person) c.newInstance("dashucoding",12);
     System.out.println(p);
     }
    }
    

    反射获取成员变量

    package com.dashucoding.demo
    public class Demo {
     public static void main(String[] args) {
      Class clazz = Class.forName("com.dashucoding.bean.Person");
    
     Constructor c = clazz.getConstructor(String.class,int.class);
      Person p = (Person) c.newInstance("dashucoding",12);
      // 获取
      Field f = clazz.getField("name");
      f.set(p, "李四");
      // Field f = clazz.getDeclaredField("name");
      // f.set(p, "李四");
     }
    }
    

    获取方法

    package com.dashucoding.demo
    public class Demo {
     public static void main(String[] args) {
      Class clazz = Class.forName("com.dashucoding.bean.Person");
    
     Constructor c = clazz.getConstructor(String.class,int.class);
      Person p = (Person) c.newInstance("dashucoding",12);
      
     //获取
     Method m = clazz.getMethod("say");
     m.invoke(p);
      
     Method m2 = clazz.getMethod("say",int.class);
     m.invoke(p,12);
     }
    }
    

    泛型

    package com.dashucoding.demo
    public class Demo {
     public static void main(String[] args) {
       ArrayList<Integer> list = new ArrayList<>();
       // list.add(1);
       Class clazz = Class.forName("java.util.ArrayList");
      Method m = clazz..getMethod("方法名", Object.class);
      m.invoke(list,"abc");
      System.out.println(list);
     }
    }
    

    propertyName改属性值

    public class Tool {
     public void setProperty (Object obj, String propertyName, Object value) throws Exception {
      Class clazz = obj.getClass();
      Field f = clazz.getDeclaredField(propertyName);
      f.setAccessible(true);
      f.set(obj, value);
     }
    }
    
    public static void main(String[] args){
     
     }
    
    class Student {
     private String name;
     private int age;
     ...
    }
    

    反射

    public class Demo {
     public void run() {
      System.out.println("dashucoding");
     }
    }
    
    // 配置文件 获取这个名词并加载这个类
    com.dashucoding.test.Demo
    
    public static void main(String[] args){
     BufferedReader br = new BufferedReader(new FileReader("xxx.properties"));
     Class clazz = Class.forName(br.readLine());
     
     Demo demo = (Demo) clazz.newInstance();
     demo.run();
    }
    

    动态代理

    public interface User {
     public void add();
     public void delete();
    }
    
    public class UserImp implements User{
     @Override 
     public void add() {
      System.out.println("添加");
     }
     @Override
     public void delete(){
      System.out.println("删除");
     }
    }
    
    public class Test {
     public static void main(String[] args){
      UserImp ui = new UserImp();
      ui.add();
      ui.delete();
     }
    }
    

    动态代理,在程序运行中产生对象。

    public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h);
    
    new ProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h);
    
    invoke(Object proxy, Method nethod, Object[] args);
    
    public class MyInvocationHandler implements InvocationHandler {
     private Object target;
     public MyInvocationHandler (Object target) {
      this.target = target;
     }
     @Override
     public Object invoke(Object proxy,Method method,object[] args) throws Throwable {
     method.invoke(target,args);
      return null;
     }
    }
    
    MyInvocationHandler m = new MyInvocationHandler(si);
    Student s = (Student)Proxy.newProxyInstance(ui.getClass().getClassLoader(), ui.getClass().getInterfaces(), m);
    

    结言

    好了,欢迎在留言区留言,与大家分享你的经验和心得。

    感谢你学习今天的内容,如果你觉得这篇文章对你有帮助的话,也欢迎把它分享给更多的朋友,感谢。

    作者简介

    达叔,理工男,简书作者&全栈工程师,感性理性兼备的写作者,个人独立开发者,我相信你也可以!阅读他的文章,会上瘾!,帮你成为更好的自己。长按下方二维码可关注,欢迎分享,置顶尤佳。

    感谢!承蒙关照!您真诚的赞赏是我前进的最大动力!

    努力努力再努力Jeskson

    相关文章

      网友评论

        本文标题:第89节:Java中的反射技术

        本文链接:https://www.haomeiwen.com/subject/rydiyqtx.html