黑马程序员-反射

---------------------- ASP.Net+Android+IOS开发</a>、 .Net培训、期待与您交流! ----------------------


反射

反射就是把Java类中的各种成份映射成相应的Java类,例如Method类、Constructor类、Field类、Package类等


反射构造方法

Method: Class<T>类
Constructor<T> getConstructor(Class<?>... parameterTypes)    //返回此字节码所表示的类的指定的public构造器
Constructor<?>[] getConstructors()    //所有public修饰的构造器
Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)    //返回指定的构造器对象(包括private)
Constructor<?>[] getDeclaredConstructors()    //获得所有声明的构造函数

T newInstance()    //创建对象,调用不带参数的构造函数

Method: Constructor<T>类
T newInstance(Object... obj)    //创建对象,obj为构造方法接收的参数

import java.lang.reflect.Constructor;
/**
通过Class对象,反射获取Constructor对象
使用Constructor对象的newInstance(Object... obj)方法创建对象
*/

class ConstructorDemo
{
    public static void main(String[] args) throws Exception
    {
        Constructor<String> con = String.class.getConstructor(StringBuffer.class);
        String str = con.newInstance(new StringBuffer("abc"));

        System.out.println(str);
    }
}


反射字段

Method: Class<T>类
Field getField(String name)    //获取指定属性的Field
Field[] getFields()    //获取所有属性的Field,返回Field[]
Field getDeclaredField(String name)    //获取指定属性的Field(包括private修饰的属性)

Method: Field类
getXxx(Object obj)    //获取obj对象中该Field的属性值,此处的Xxx对应8种基本类型,如果该属性的类型是引用类型则取消get后面的Xxx
setXxx(Object obj, Xxx val)    //将obj对象的该Field设置成val值。此处Xxx对应8种基本类型,如果该属性是引用则取消set后面的Xxx

import java.lang.reflect.*;
/**
通过反射方式访问属性值
*/
 
class Person
{
    private String name;
    public int age;
}
 
public class FieldTest
{
    public static void main(String[] args) throws Exception
    {
        Person p = new Person();
 
        //获取Person类对应的字节码
        Class<Person> personClazz = Person.class;
 
        Field ageField = personClazz.getField("age");
        ageField.setInt(p , 30);
        System.out.println(ageField.getInt(p));
 
        //获取Person类中名为name的属性,使用getDeclaredField可以获取private修饰的属性
        Field nameField = personClazz.getDeclaredField("name");
        //设置通过反射访问该Field时取消访问权限检查:暴力反射
        nameField.setAccessible(true);
        //调用set方法为p对象的指定Field设置值
        nameField.set(p , "zhangsan");
        //调用get方法获取p对象中的name属性值
        System.out.println(nameField.get(p));
    }
}


反射方法

Method: Class<T>类
Method getMethod(String name, Class<?>... parameterTypes)    //如获取show(String str, int i)方法:getMethod(show, String.class, Integer.class)
Method[] getMethods()    //获取所有方法实例到Method[]中
Method getDeclaredMethod(String name, Class<?>... parameterTypes)
Method[] getDeclaredMethods()

Method: Method类
Object invoke(Object obj, Object... args)    //obj是执行方法的对象,args是执行方法时传入方法的实参

注意:
如果执行的是静态方法,obj为null
如果没有参数,因为args为可变参数,可以不填,所以无参数时不需要填参数

import java.lang.reflect.Method;
/**
反射的方式调用方法
*/
 
class Person
{
    private void show()
    {
        System.out.println("hello");
    }
 
    public void show(String str1, String str2)
    {
        System.out.println(str1+str2);
    }
 
    public static void show(int i)
    {
        System.out.println(i);
    }
}
 
class MethodReflectTest
{
    public static void main(String[] args) throws Exception
    {
        Person p = new Person();
 
        Class<?> clazz = p.getClass();
 
        //调用public方法
        Method showMethod2 = clazz.getMethod("show", String.class, String.class);
        showMethod2.invoke(p, "ab", "cd");
 
        //调用私有方法
        Method showMethod1 = clazz.getDeclaredMethod("show");
        showMethod1.setAccessible(true);
        showMethod1.invoke(p);
 
        //调用静态方法
        Method showMethod3 = clazz.getMethod("show", int.class);
        showMethod3.invoke(null, 9);
    }
}


数组的反射

具有相同维数和元素类型的数组属于同一个类型,即具有相同的字节码

代表数组的Class对象调用getSuperClass()方法返回的是Object字节码

非基本类型的一维数组,既可以当作Object类型使用,又可以当作Object[]类型使用,基本类型的一维数组只可以当作Object类型使用

import java.lang.reflect.Array;
/**
数组的反射应用
*/

class ArrayReflect
{
    public static void main(String[] args)
    {
        int[] arr1 = new int[]{1, 2, 3};

        String str = "abc";

        printObject(arr1);
        printObject(str);
    }

    public static void printObject(Object obj)
    {
        Class clazz = obj.getClass();

        //如果是数组
        if(clazz.isArray())
        {
            //获取数组长度,Array类代表数组类型
            int len = Array.getLength(obj);
            for(int i = 0; i < len; i++)
            {
                System.out.println(Array.get(obj, i));
            }
        }
        else
        {
            System.out.println(obj);
        }
    }
}




---------------------- ASP.Net+Android+IOS开发</a>、 .Net培训、期待与您交流! ----------------------
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值