java基础-反射3(反射,反射创建对象,操作对象属性,调用对象方法)

来源:互联网 发布:音效管理器软件下载 编辑:程序博客网 时间:2024/06/10 22:03

java基础-反射3(反射,反射创建对象,操作对象属性,调用对象方法)

前面通过学习,我们了解的运行时类型信息的基本原理,以及通过Class对象和反射来获取运行时类型信息。下面来了解通过反射来创建对象,以及操作对象的属性和方法

首先还是创建一个person类

@Servicepublic class Person1 extends PersronParent implements PersonInterfance ,Cloneable{    public  String name;    public  double weight;    protected  double height;    private Integer age;    public Person1(){}    protected Person1(String name){    }    public void publicShow() throws Exception{        System.out.println("publicShow()");    }    protected void disPlay(){        System.out.println("disPlay()");    }    private String privateShow(String paramter1,String paramter2) throws NullPointerException{        StringBuffer stringBuffer  = new StringBuffer(paramter1);        return stringBuffer.append(paramter2).toString();    }    @Deprecated    private int testParamter(String paramter1,String paramter2) throws NullPointerException{        return 1;    }    @Deprecated    public int testPublicParamter(String paramter1,String paramter2) throws NullPointerException{        return 1;    }    @Override    public void parentSay(){        super.parentSay();    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public double getWeight() {        return weight;    }    public void setWeight(double weight) {        this.weight = weight;    }    public double getHeight() {        return height;    }    public void setHeight(double height) {        this.height = height;    }    public Integer getAge() {        return age;    }    public void setAge(Integer age) {        this.age = age;    }    @Override    public String toString() {        return "Person{" +                "name='" + name + '\'' +                ", weight=" + weight +                ", height=" + height +                ", age=" + age +                '}';    }

通过反射来创建对象

通常在java中我们有以下4中方式创建对象

  1. 通过new 关键字 创建对象
  2. 通过Object clone();方法
  3. 通过反序列化
  4. 通过反射创建

这里我们来了解通过反射来创建对象和调用方法

首先我们来看通过反射来创建对象
我们通过newInstance()来创建对象,如果对于无参数的构造方法我们直接用Class的对象的newInstance()就可以创建对象
如果对于有参数的构造方法,我们需要先获取带参数的构造器(注意权限修饰符),然后通过构造器的newInstance()方法创建对象。

public class TestReflect {    public static void main(String[] agrs){            Class<Person> personClass = Person.class;            try {                /**                 * 通过无参数的构造方法创建对象                 */                Person personOne =   personClass.newInstance();                /**                 * 通过有参数的构造方法创建对象                 */                Constructor constructor = personClass.getDeclaredConstructor(String.class);                Person personTwo =   (Person) constructor.newInstance("带参数");            } catch (InstantiationException e) {                e.printStackTrace();            } catch (IllegalAccessException e) {                e.printStackTrace();            } catch (NoSuchMethodException e) {                e.printStackTrace();            } catch (InvocationTargetException e) {                e.printStackTrace();            }    }}

运行结果如下
这里写图片描述

这样我们就可以通过反射来创建对象。
通过反射创建对象后可以通过反射来给操作对象的属性

通过反射操作对象属性

上一篇文章说过,类的属性在反射中使用java.lang.reflect.Field表示,当然也使用这个类来操作对象的属性,在java中属性的访问涉及到权限修饰的修饰,具体如下:
这里写图片描述

所以在操作对象的属性的需要注意对目标类属性访问的权限,如下
如果当前类对目标对象有访问的权限(如目标类属性为public)

  1. 通过Class对象的getField()获取Field。
  2. 然后通过Field的set()方法对目标对象赋值。

如果当前类对目标对象没有访问的权限(如目标类属性为private)

  1. 通过Class对象的getDeclaredField()获取Field。
  2. 调用Field 的setAccessible(true)方法,设置为可访问(如果不设置为true,则在当前类中不能访问目标类的属性,在为目标对象赋值时会报错)
  3. 然后通过Field的set()方法对目标对象赋值。
  4. 调用Field 的setAccessible(false)方法复原。

具体操作如下

public class TestFileId2 {    public static void main(String agrs[]) throws NoSuchFieldException {        try {            //获取Class 对象            Class<Person> personClass  = Person.class;            //创建目标对象(注意,我们这里直接用的object,更体现了运行时类型信息)            Object person = personClass.newInstance();            //在没有通过反射赋值之前            System.out.println("person对象在没有赋值之前");            System.out.println(person.toString());            System.out.println();            System.out.println("当前类可以操作目标类的属性:比如public权限的属性");            //获取有权限操作的属性(当前类可以操作目标对象的属性:比如public)            Field name = personClass.getField("name");            //为person 对象 的 name属性赋值为 TestName            name.set(person,"TestName");            System.out.println(person.toString());            System.out.println();            System.out.println("当前类不能够操作目标类的属性:比如private权限的属性");            Field age = personClass.getDeclaredField("age");            //为person 对象 的 age 属性设置为可访问            age.setAccessible(true);            //为person 对象 的 age属性赋值为 10            age.set(person,10);            age.setAccessible(false);            System.out.println(person.toString());        } catch (InstantiationException e) {            e.printStackTrace();        } catch (IllegalAccessException e) {            e.printStackTrace();        }    }}

运行结果如下
这里写图片描述

通过反射调用对象方法

反射能够操作对象的属性,当然也可以操作对象的方法,方法通过java.lang.reflect.Method表示,由于访问权限的限制,对于方法也有如下操作
如果当前类对目标对象有访问的权限(如目标类方法为public)

  1. 通过Class对象的getMethod()获取Method。
  2. 然后通过Method的invoke()方法对目标对象赋值。

如果当前类对目标对象没有访问的权限(如目标类方法为private)

  1. 通过Class对象的getDeclaredMethod()获取Method。
  2. 调用Method的setAccessible(true)方法,设置为可访问(如果不设置为true,则在当前类中不能访问目标类的方法,在调用目标类的方法时会报错)
  3. 然后通过Method的invoke()方法对目标对象赋值。
  4. 调用Method的setAccessible(false)方法复原。

具体操作如下:

public class TestMethod2 {    public static void main(String agrs[]) throws NoSuchFieldException, NoSuchMethodException, InvocationTargetException {        try {            //获取Class 对象            Class<Person> personClass = Person.class;            //创建目标对象            Object person = null;            person = personClass.newInstance();            System.out.println("当前类可以操作目标类的方法:比如public权限的方法");            //获取有权限操作的方法(当前类可以操作目标对象的方法:比如public)            Method publicShow = personClass.getMethod("publicShow");            //通过Method 的invoke 调用person 的 publicShow方法            publicShow.invoke(person);            System.out.println("当前类不能够操作目标类的方法:比如private权限的方法");            Method privateShow = personClass.getDeclaredMethod("privateShow", String.class, String.class);            //为person 对象 的 privateShow 方法设置为可访问            privateShow.setAccessible(true);            //通过Method 的invoke 调用person 的 privateShow方法            String result = (String) privateShow.invoke(person, "参数1", "参数2");            System.out.println(result);        } catch (InstantiationException e) {            e.printStackTrace();        } catch (IllegalAccessException e) {            e.printStackTrace();        }    }}

运行结果如下:
这里写图片描述

以上就是通过反射操作对象的基本方式。

反射的基础知识就是以上几篇文章,反射相对于其他知识来说比较简单,但是反射应用很多,比如很多框架,以及java中的动态代理等都涉及到了,所以反射在java中还是很重要的。

原创粉丝点击