反射的学习与应用

反射的学习与应用

1. 类对象

1.1 概念
Java 中有一个类,java.lang.Class 类。这个类的对象,就被称之为类对象。

源代码编写好后进行编译后产生的.class文件就是一个类对象

1.2 获取类对象
类名.class

 Class c = Sports.class;
 Class c2 = int.class;
 System.out.println(c);
 System.out.println(c2);

结果为:
在这里插入图片描述
c为类全名,c2为 int 数据类型

对象.getClass()

 Sports p = new Sports();
        System.out.println(p.getClass());

结果为:
在这里插入图片描述
Class.forName()

 try {
            Class c3 = Class.forName("com.qf.day09.t5.Sports");
            System.out.println(c3);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

结果为:
在这里插入图片描述
1.3 使用类对象获取类的信息
当我们获得了类对象,当然就可以调用类对象中的方法。
例如:

  • getName(): 获得类的名称,包括包名
  • getSimpleName(): 获得类的名称,不包括包名
  • getSuperClass(): 获得本类的父类的类对象
  • getInterfaces() : 获得本类所实现的所有接口的类对象,返回值类型为 Class[],当然, 这是对的,一个类可以实现多个接口

1.4 使用类对象获取类中方法的信息
在 Class 类中,有两个方法,这两个方法签名如下:

  • public Method[] getDeclaredMethods() throws SecurityException
  • public Method[] getMethods() throws SecurityException

getMethods() 方法
返回的 Method 类型的数组中,包括所有的公开方法,也包括 父类中定义的公开方法

Method[] ms = c.getMethods();
        for(int i = 0; i < ms.length; i++){
            System.out.println(ms[i]);
        }

结果为:
反射的学习与应用_第1张图片
** getDeclaredMethods ()方法**
会返回在本类中定义的所有方法,包括私有方法

 Method[] ms6 = c.getDeclaredMethods();
        for(int i = 0; i<ms6.length; i++){
            System.out.println(ms6[i].toString());
        }

反射的学习与应用_第2张图片
1.5 使用类对象创建对象
newInstance(),这个方法能够通过类的无参构造方法,创建一个对 象。

 try {
            Sports sports = (Sports)c.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } 

结果为;
在这里插入图片描述
2.1 反射包
Field 类封装了属性信息,一个Field对象封装了一个属性的信息。
getField(String name)
可以获得本类的公开书信和以及从父类继承到的公开属性,但是无法获得非公开属性

  public  static  void test(){
        Student stu = new Student();

        Class c = stu.getClass();
        try {
            Field nameFile = c.getField("name");
            nameFile.set(stu,"tom");
            Object value1 = nameFile.get(stu);
            System.out.println(value1);
        }catch (Exception e){
            e.printStackTrace();
        }

    }

结果为:
在这里插入图片描述
getDeclaredMethods(String name)
getDeclaredMethods方法只能获得本类属性,但包括本类的非公开属性

  public  static  void test(){
        Student stu = new Student();

        Class c = stu.getClass();
        try {
            Field f = c.getDeclaredField("name");
           f.set(stu,"tom");
            Object value = f.get(stu);
            System.out.println(value);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

结果为:
在这里插入图片描述
私有属性 setAccessible
除了能够获得 类中的公开属性之外,利用反射还能获得并修改对象的私有属性。

Field无法获得父类的私有属性

 public  static  void test2(){
        Student stu = new Student();
        try {
           Field f = stu.getClass().getDeclaredField("age");
           f.setAccessible(true);
           f.set(stu,new Integer(18));
           Object value = f.get(stu);
            System.out.println(value);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

结果为:
在这里插入图片描述
Method类
public Method getMethod(String name,Class[] parameterTypes)
public Method getDeclaredMethod(String name,Class[] parameterTypes)
两个方法的区别同样与 getMethods 方法和 getDeclaredMethods 方法类似。
getMethod 可 以获得公开方法,包括父类的;getDeclaredMethod 只能获得本类的方法,但不限于公开方 法。
getMethod 以及 getDeclaredMethod 方法有两个参数。
第一个参数是一个字符串参数,表示的是方法的方法名。
第二个为个方法的参数表。

public  static  void test3(){
        Student stu = new Student();
        Class c= stu.getClass();
        try {
            Field  f =  stu.getClass().getDeclaredField("name");
            f.set(stu,"wangwu1");
            Method m = c.getDeclaredMethod("study",new Class[]{int.class,double.class});
            Object result = m.invoke(stu,new  Object[]{new Integer(10),new Double(1.5)});
            System.out.println(result.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

Constructor类
Constructor类封装了构造函数的信息

  1. 通过 Class 类中的 getConstructors() / getDeclaredConstructors()获得 Constructor 数组。
  2. 可以通过 Class 类中的 getConstructor() / getDeclaredConstructor()来获得指定的构 造方法。
  3. ,可以调用 Constructor 类中的 newInstance 方法创建对象

如果创建对象只需要调用无参构造方法的话,就可以直接使用 Class 类中的 newInstance 方法,如果在创建对象的时候需要指定调用其他构造方法的话,就需要使用 Constructor 类。

public class TestConstructor {
    public static void main(String[] args) {

        try {
            Class c= Dog.class;
            Dog d1 = (Dog) c.newInstance();
            System.out.println(d1);
            Constructor con = c.getConstructor(new Class[]{String.class,int.class});
            Dog d2 =(Dog) con.newInstance(new Object[]{"Snoopy",new Integer((5))});
            System.out.println(d2);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

结果为
反射的学习与应用_第3张图片
工厂模式点击可查看
单例模式点击可查看

你可能感兴趣的:(java)