java 反射机制的基本知识

    xiaoxiao2021-03-25  67

    一下均是来自己看自李兴华老师的视频笔记,他讲的视频挺好的,自己写的估计只能自己看的懂,想更加清楚的了解,请观看他的视频。

    前天看那个java学习路线的一张图上看了看,里面有一节内容讲的是反射,我就搜集资料视频学了学。

    我们平常访问普通的方法都是在哪里进行使用new进行创建对象,再利用创建的对象进行访问这个方法。

    那么我们如何在不使用new关键字的情况下进行访问这些对象和属性呢?new关键字是造成耦合度高的重要原因

    Java 的反射就是在程序动态的运行中进行访问方法和属性;

    一般来说创建并实例化一个程序一般有三种方法:通过new关键字  --   通过 clon -- 另一种就是反射,今天说说反射。

    先看一下怎么利用反射进行创建对象和实例化。

    一、利用反射进行创建对象和实例化。

    Person类就不贴了,就是有两个属相private String name ,private int age,属性设置get set toString 方法

    [java]  view plain  copy   package com.hejingzhou.tcoy;         public class Test {   public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {      Person person = new Person();   Class cla_1 = person.getClass();   Object obj_1 = cla_1.newInstance();   System.out.println(obj_1);   System.out.println("###############################");         Class cla_2 = Person.class;   Object obj_2 = cla_2.newInstance();   System.out.println(obj_2);   System.out.println("###############################");      Class cls_3 = Class.forName("com.hejingzhou.tcoy.Person");   System.out.println(cls_3);//获的是 完整的类   Object obj_3 = cls_3.newInstance();   //Person person = (Person)obj_3;   //System.out.println(person.getAge());   System.out.println(obj_3);   }   }  

    二、反射创建对象实例的应用

    [java]  view plain  copy   interface IFruit{       void eat();   }      class Apple implements IFruit{          public void eat() {           // TODO Auto-generated method stub           System.out.println("吃苹果");       }      }   class Orange implements IFruit{          public void eat() {           // TODO Auto-generated method stub           System.out.println("吃橘子");       }      }      class Factoty{       public static IFruit getInstance(String className) throws InstantiationException, IllegalAccessException, ClassNotFoundException{   //使用反射前的工厂模式,每次添加新的水果就得需要进行修改工厂模式类中的if语句   //      if(className.equals("Apple")){   //          return new Apple();   //      }           /***           * 使用后只需要填入类的详细类名就可以           */           IFruit fruit = null;           fruit = (IFruit) Class.forName(className).newInstance();           return fruit;       }   }      public class Test {       public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException {   //<span style="white-space:pre">      </span>Factoty.getInstance("Apple");//使用反射机制之前的工厂模式           IFruit fApple = Factoty.getInstance("com.hejingzhou.q.Orange");           fApple.eat();       }   }   这样做出的应用更适用于更改信息,非开发人员更容易进行操作。

    三、利用反射进行设置一个基本的属性

    看一下这里的Book 类 [java]  view plain  copy   package com.hejingzhou.r;      class Book {       private  String title;          public String getTitle() {           return title;       }          public void setTitle(String title) {           this.title = title;       }          public String toString() {           return "Book [title=" + title + "]";       }          }   Test一下 [java]  view plain  copy   package com.hejingzhou.r;      import java.lang.reflect.Field;      public class Test {       public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException {           Class cls = Class.forName("com.hejingzhou.r.Book");           Object obj = cls.newInstance();           Field titleField = cls.getDeclaredField("title");           titleField.setAccessible(true);//取消程序入口检查  否则title是private修饰的,是无法访问的           titleField.set(obj,"Java开发");           System.out.println(titleField.get(obj));       }      }   打印结果:Java开发 Field类就是一个动态访问类或接口的字段的入口。 [java]  view plain  copy   public Field getDeclaredField(String name)                          throws NoSuchFieldException,                                 SecurityException   Returns a Field object that reflects the specified declared field of the class or interface represented by this Class object. The name parameter is a String that specifies the simple name of the desired field.   [java]  view plain  copy   public void setAccessible(boolean flag)                      throws SecurityException   Set the accessible flag for this object to the indicated boolean value. A value of true indicates that the reflected object should suppress Java language access checking when it is used. A value of false indicates that the reflected object should enforce Java language access checks   [java]  view plain  copy   set(Object obj, Object value)   Sets the field represented by this Field object on the specified object argument to the specified new value.   这样就可以动态的设置字段参数。

    四、动态的设置构造方法

    Book类必须有一个空参构造 [java]  view plain  copy   package com.hejingzhou.w;      public class Book {       private String title;       private double price;          public Book(){       }              public Book(String title){           this.title = title;           System.out.println("我是只有一个参数的构造方法");       }              public Book(String title, double price) {           super();           this.title = title;           this.price = price;       }       public String toString() {           return "Book [title=" + title + ", price=" + price + "]";       }          }   详细的管理构造参数一下 [java]  view plain  copy   package com.hejingzhou.w;      import java.lang.reflect.Constructor;   import java.lang.reflect.InvocationTargetException;      public class Test {       public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {           Class cls = Class.forName("com.hejingzhou.w.Book");   //      Object apogee = cls.newInstance();//这样实例化  就只能调用 类中默认的无参构造方法   //      System.out.println(obj);                      Constructor constructor = cls.getConstructor(new Class[]{String.class,double.class});           Object object = constructor.newInstance(new Object[]{new String("Java开发"),new Double(43.9)});//"Java开发",43.2           System.out.println(object);                      Constructor constructor2 = cls.getConstructor(new Class[]{String.class});           Object object2 = constructor2.newInstance(new Object[]{new String("Android开发")});           System.out.println(object2);                  }   }   这是java1.8环境下在进行构造方法赋值 的时候进行需要创建一个Object类型数组进行添加对应的数据,但是在视频中,是直接进行赋值的,这点需要注意,

    五、操作get set 方法

    Frult类(操作类) [java]  view plain  copy   package com.hejingzhou.e;      public class Fruit {          private String name;          public String getName() {           return name;       }          public void setName(String name) {           this.name = name;       }          public String toString() {           return "Fruit [name=" + name + "]";       }          }   进行设置操作get set方法的操作 [java]  view plain  copy   package com.hejingzhou.e;      import java.lang.reflect.InvocationTargetException;   import java.lang.reflect.Method;      public class Test {       public static void main(String[] args) throws ClassNotFoundException,       InstantiationException, IllegalAccessException, NoSuchMethodException,        SecurityException, IllegalArgumentException, InvocationTargetException {           String fieldName = "name";           Class cla = Class.forName("com.hejingzhou.e.Fruit");           Object obj = cla.newInstance();           //System.out.println(obj);           Method setMet = cla.getMethod("set"+initCap(fieldName), new Class[]{String.class});           Method getMet = cla.getMethod("get"+initCap(fieldName), null);           setMet.invoke(obj,new Object[]{new String("java 开发")} );           System.out.println(getMet.invoke(obj, null));       }       //返回字符串首字母大写       public static String initCap(String str){           return str.substring(0,1).toUpperCase()+str.substring(1);       }   }   打印结果 Book [title=Java开发, price=43.9] 我是只有一个参数的构造方法 Book [title=Android开发, price=0.0] 这样就可以进行控制方法了。 这就是反射的基本应用,一般都应用与框架中。
    转载请注明原文地址: https://ju.6miu.com/read-38119.html

    最新回复(0)