java反射(一)

反射

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。

文中所使用的Person.class附于最后

package cn.my.Reflect;

/**
 * 反射:就是通过class文件对象,去使用该文件的成员变量、构造方法使用成员变量、构造方法。
 * 以前使用成员变量、构造方法使用成员变量、构造方法:
 * >Person p = new Person;
 * >通过p来使用
 * 
 * 现在使用成员变量、构造方法使用成员变量、构造方法:
 * >要想这样使用,首先你必须得到class文件对象,其实就是得到Class类对象
 * 
 * Class 类:
 *  >成员变量 Field
 *  >构造方法 Constructor 
 *  >成员方法 Method
 * 获取Class文件对象的方式:如下代码中三种方式。
 *
 */
public class ReflectDemo {
    public static void main(String[] args) throws ClassNotFoundException {
        //方式一
        Person p = new Person();
        Class c = p.getClass();

        Person p2 = new Person();
        Class c2 = p2.getClass();

        System.out.println(p==p2);//false
        System.out.println(c==c2);//true

        //方式二
        Class c3 = Person.class;
        //int.class;
        //String.class;
        System.out .println(c==c3);//true

        //方式三
        //ClassNotFoundException,找类时要全路径,带包名
//      Class c4 =Class.forName("Person");
//      System.out.print(c==c4);//报错
        //cn.my.Reflect.Person
        Class c4 =Class.forName("cn.my.Reflect.Person");
        System.out.print(c==c4);//true

     }
}

一般使用选择: 项目开发:方式三:方式三是一个字符串,而不是一个具体的类名。这样可以把这样的字符串配置到配置文件中。

通过反射获取构造方法并使用

获取无参构造方法

package cn.my.Reflect_02;

import java.lang.reflect.Constructor;

/*
 * 通过反射获取构造方法并使用
 */
public class ReflectDemo {
    public  static void main(String[] args) throws Exception {
        //获取字节码文件对象
        Class c = Class.forName("cn.my.Reflect_01.Person");

//      /*获取构造方法
//      *public Constructor[] getConstructors();拿到所有公共构造方法
//      *public Constructor[] getDeclaredConstructors();拿到所有的构造方法
//      */
//      Constructor[] cons = c.getConstructors();//拿到所有公共构造方法
//      Constructor[] cons = c.getDeclaredConstructors();//拿到所有的构造方法
//      for(Constructor con : cons) {
//          System.out.println(con);        
//      }
        //获取单个构造方法
        /*public Constructor getConstructor(Class<?>... parameterTypes)
         * 参数表示是:你要获取的构造方法的构造参数个数和数据类型的class字节码文件对象
         */
        Constructor con = c.getConstructor();//返回的构造方法对象
        //public T newInstance(Object... initargs)
        //使用此Constructor对象表示的构造方法来创建该构造方法的声明类的新实例,并用户指定的初始化参数初始化该实例。
        Object obj = con.newInstance();
        System.out.println(obj);
    }
}

反射获取带参构造器并使用

package cn.my.Reflect_02;

import java.lang.reflect.Constructor;

/*
 * 需求:通过反射去获取该构造方法并使用:
 * public Person(String name, int age, String address)
 */
public class ReflectDemo2 {
    public static void main(String[] args) throws Exception{
        //获取去字节码文件对象
        Class c = Class.forName("cn.my.Reflect_01.Person");

        //获取带参构造器
        //public Constructor getConstructor(Class<?>... parameterTypes)
        Constructor con = c.getConstructor(String.class, int.class, String.class);

        //通过带参构造方法对象创建对象
        //public T newInstance(Object... initargs)
        Object obj = con.newInstance("林青霞", 27 , "北京");
        System.out.println(obj);
    }
}

反射获取并使用私有的构造方法

package cn.my.Reflect_02;

import java.lang.reflect.Constructor;

import javax.print.attribute.standard.PrinterLocation;
/*
 * 需求:通过反射获取私有构造方法并使用
 * private Person(String name){}
 */
public class ReflectDemo3 {
    public static void main(String[] args) throws Exception {
        Class c = Class.forName("cn.my.Reflect_01.Person");

        //Constructor con = c.getConstructor(String.class);报错NoSuchMethodException,因为这个只能获取公共的构造参数。
        Constructor con = c.getDeclaredConstructor(String.class);//报错IllegalAccessException,非法的访问

        con.setAccessible(true);//值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查。
        Object obj = con.newInstance("张伟");
        System.out.println(obj);
    }
}

反射获取成员变量并使用

package cn.my.Reflect_03;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.jar.Attributes.Name;

/*
 * 通过反射获取成员变量并使用
 */
public class ReflectDemo1 {

    public static void main(String[] args) throws Exception {
        Class c = Class.forName("cn.my.Reflect_01.Person");

        //获取所有的成员变量
        //Field[] fields =c.getFields();只能获取公共的成员变量
        Field[] fields = c.getDeclaredFields();//获取所有的成员变量
        for(Field field : fields) {
            System.out.println(field);
        }

        /*
         * Person p = new Person();
         * p.address = "四川"
         */
        //通过无参构造方法创建对象
        Constructor con = c.getConstructor();
        Object obj = con.newInstance();

        //获取单个成员变量
        //获取address并对其赋值
        Field addressFild = c.getField("address");
        //public void set(Object obj, Object value)将指定对象变量上此 Field 对象表示的字段设置为指定的新值
        addressFild.set(obj,"四川"); //给obj对象的addressField字段设置值为“四川”;
        System.out.println(obj);

        //获取age并对其赋值
        Field nameField = c.getDeclaredField("name");
        nameField.setAccessible(true);//Person的name是私有的成员变量
        nameField.set(obj, "张三");
        System.out.println(obj );
    }   
}

反射获取成员方法并使用

package cn.my.Reflect_04;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

public class ReflectDemo1 {
    public static void main(String[] args) throws Exception {
        Class c = Class.forName("cn.my.Reflect_01.Person");

        //获取所有的方法
//      Method[] methods = c.getMethods();//获取自己的包括父亲的方法
        Method[] methods = c.getDeclaredMethods(); //获取自己的所有的方法
        for(Method method : methods) {
            System.out.println(method);
        }

        Constructor con = c.getConstructor();
        Object obj = con.newInstance();

        //获取单个方法并使用

        /**
         * 调用无参的公共类型的方法
         * 调用Person中的public void show()方法
         * 相当于Person p = new Person(); p.show();
         */

        /*
         *public Method getMethod(String name, Class<?>... parameterTypes)
         *name用于指定所需方法的简称。
         *parameterTypes 参数是按声明顺序标识该方法形参类型的 Class 对象的一个数组,如果 parameterTypes 为 null,则按空数组处理
         */
        Method m1 = c.getMethod("show");
        //public Object invoke(Object obj, Object... args)
        //返回值是Object接收,第一个参数表示对象是谁,第二个参数表示调用该方法的实际参数
        m1.invoke(obj);//调用obj对象的m1方法。

        /**
         * 调用带一个参的方法
         * 调用public void method(String string){}方法
         */
        Method m2 = c.getMethod("method", String.class);
        m2.invoke(obj, "hello");

        /**调用带多个参数的方法
         * public String getString(String s,int i){ }
         */
        Method m3 = c.getMethod("getString", String.class , int.class);
        Object obgString = m3.invoke(obj, "hello" ,100);
        //String s = m3.invoke(obj, "hello" ,100);//得到返回值
        System.out.println(obgString);

        /**
         * 调用一个私有方法
         * private void function() {}
         */
        Method m4 = c.getDeclaredMethod("function");
        m4.setAccessible(true);
        m4.invoke(obj);
    }
}

Person.class

package cn.my.Reflect_01;

public class Person {
    private String name;
    int age;
    public String address;
    public String getName() {
        return name;
    }

    public Person() {
        super();
    }
    private Person(String name) {
        this.name = name;
    }
    Person(String name,String address) {
        this.name = name;
        this.address = address;
    }
    public Person(String name, int age, String address) {
        super();
        this.name = name;
        this.age = age;
        this.address = address;
    }
    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + ", address=" + address + "]";
    }

    public void show() {
        System.out.println("show");
    }
     private void function() {
         System.out.println("function");

     }
     public void method(String string) {
         System.out.println("method  "+string);

     }

     public String getString(String s,int i) {
         return s+" "+i;

     }  
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值