java基础——反射

反射:就是把java类中的各种成分映射成相应的java类
反射一般有,对类的构造函数进行反射,对类中的成员变量进行反射,对类中的成员方法进行反射,对数组进行反射。

//获取Class对象的三种方法即获取类的字节码文件,以String类为例
class GetInstance
{
    public static void main(String[] args)throws Exception
    {
        getClassIns();
        isPrimitive();
    }
    public static void getClassIns()throws Exception 
    {
        String str = "abc";
        //第一种直接 类名.class 就是代表该类所对应的字节码文件,即class文件
        Class c1 = String.class;
        //通过所需类的对象调用getClass()方法,getClass()方法是Object类中的方法
        Class c2 = str.getClass();
        //通过Class类中的静态方法forName(String className),参数为该类所在的具体位置
        Class c3 = Class.forName("java.lang.String");

        System.out.println(c1==c2);
        System.out.println(c1==c3);
    }

    //判断该类的字节码文件是否为基本数据类型的字节码文件
    public static void isPrimitive()
    {
        System.out.println(int.class.isPrimitive());//true
        System.out.println(Integer.class.isPrimitive());//false
        System.out.println(int.class==Integer.TYPE);//true  
        //基本数据类型的包装类调用TYPE字段返回该类对应的基本数据类型
    }
}

反射取出类中的构造函数:
getConstructor(parameterTypes)
返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法。
getConstructors()
返回一个包含某些 Constructor 对象的数组,这些对象反映此 Class 对象所表示的类的所有公共构造方法。

//获取类的一个具体的构造方法 如用反射的方法实现 new Integer("123") new Integer(new String("456"));
public static void getCon()throws Exception
{
    //获取Integer类中带有String参数的构造方法
    //Constructor con = Integer.class.getConstructor(String.class);
    Constructor con = Class.forName("java.lang.Integer").getConstructor(String.class);

    //将获取到的构造方法实例化,并按照要求往其中传入参数
    //Integer in = (Integer)con.newInstance("123");
    Integer in = (Integer)con.newInstance(new String("456"));
    System.out.println(in);
}

反射取出类中的成员变量:
Field getDeclaredField(String name)
返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段。
Field[] getDeclaredFields()
返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段。
Object get(Object obj)
返回指定对象上此 Field 表示的字段的值

class GetField
{
    public static void main(String[] args)throws Exception
    {
        getFie();
        Demo d = new Demo(1,2);
        System.out.println(d);
        replaceFields(d);
        System.out.println(d);
    }

    //获取一个类中的成员变量
    public static void getFie()throws Exception
    {
        Demo d = new Demo(5,6);
        //获取公共成员X字段,它是一个对象,并不是具体的值
        Field fieldX = d.getClass().getField("x");
        //获取指定对象上X字段对应的值
        int x = (int)fieldX.get(d);

        //获取声明过的字段
        Field fieldY = d.getClass().getDeclaredField("y");
        //将私有的字段暴露
        fieldY.setAccessible(true);
        int y = (int)fieldY.get(d);
        System.out.println(y);
    }
    //用反射的方法将一个类中所有String类型的字段中的'a'改成'c'
    public static void replaceFields(Object obj) throws Exception
    {
        Field[] fields = obj.getClass().getFields();
        for (Field field : fields )
        {
            //取出指定类型的字段
            if(field.getType()==String.class)
            {
                String value = (String)field.get(obj);
                //替换值
                String newValue = value.replace('b','a');
                //System.out.println(newValue);
                //将改变后的新值重新设置到指定对象的字段中
                field.set(obj,newValue);
            }
        }
    }
}
class Demo 
{
    public int x ;
    private int y ;
    public String a = "aabbccddaa";
    public String b = "123aa33bb3tt";
    public String c = "javadoc";

    Demo(int x,int y)
    {
        this.x = x ;
        this.y = y ;
    }

    public String toString()
    {
        return a+"  "+b+"  "+c ;
    }
}

反射取出类中的成员方法:
Method getDeclaredMethod(name,parameterTypes)
返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法。
Method[] getDeclaredMethods()
返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。
Object invoke(Object obj, Object… args)
对带有指定参数的指定对象调用由此 Method 对象表示的底层方法。

class GetMethod
{
    public static void main(String[] args)throws Exception
    {
        getMain();
        getMe();
    }
    //获取类中的方法,并调用 如String类中的indexOf(String str)
    public static void getMe() throws Exception
    {
        String str = "abc";
        Method method = String.class.getMethod("indexOf",String.class);
        //indexOf指的是要获取的具体方法 String.class 指的是方法的参数类型,可以有多个参数
        int in = (int)method.invoke(str,"b");//可以理解为是String类对象调用indexOf方法,参数是"b"
        System.out.println(in);
    }
    //反射调用一个类中的main方法
    public static void getMain() throws Exception
    {
        //Method method = Class.forName("ForDemo").getMethod("main",String[].class);
        Method method = ForDemo.class.getMethod("main",String[].class);

        //如果方法是静态的,则第一个参数为null,因为不需要对象调用
        //method.invoke(null,new Object[]{new String[]{"12","23","34"}});
        method.invoke(null,(Object)new String[]{"12","23","34"});       
    }
}

class ForDemo
{
    public static void main(String[] args)
    {
        for (String arg : args )
        {
            System.out.println(arg);
        }
    }
}

对数组进行反射:
boolean isArray()
判定此 Class 对象是否表示一个数组类。
static Object get(Object array, int index)
返回指定数组对象中索引组件的值。
static int getLength(Object array)
以 int 形式返回指定数组对象的长度

class GetArr
{
    public static void main(String[] args)throws Exception
    {
        String[] str = {"25","56","78"};
        reflectArr(str);

        String str1 = "256879";
        reflectArr(str1);

        int[] arr = {1,8,6,4,8};
        reflectArr(arr);        
    }
    //对数组进行反射,数组是引用数据类型,属于Object类
    public static void reflectArr(Object obj) throws Exception
    {
        Class cla = obj.getClass();
        //判断是否为数组
        if (cla.isArray())
        {
            //通过对象获取数组的长度
            int len = Array.getLength(obj);
            for (int x=0;x<len ;x++ )
            {
                //获取数组中角标对应的值
                System.out.println(Array.get(obj,x));
            }
        }
        else 
            System.out.println(obj);
    }
}

反射的应用:
用反射做一个简单的框架:如不使用具体的集合中的类,通过配置文件取出集合类并实现集合类的功能
思路:
1.写一个配置文件,用键值对的形式表示出具体的类的限定名
2.用Properties集合将集合与输入流相结合
3.取出键对应的值,即类的限定名
4.利用反射获取类并将其实例化,则可以取到具体的集合
5.对集合进行操作

import java.util.*;
import java.lang.reflect.*;
import java.io.*;

class ReflectTest
{
    public static void main(String[] args) throws Exception
    {
        ReflectColl();
    }
    public static void ReflectColl() throws Exception
    {
        //和指定的文件相关联
        InputStream in = new FileInputStream("Coll.properties");
        Properties prop = new Properties();
        //读取输入流中的属性列表
        prop.load(in);
        //关闭资源
        in.close();
        //通过键取值,可以得到类的限定名
        String className = prop.getProperty("className");
        //创建此 Class 对象所表示的类的一个新实例。
        Collection coll = (Collection)Class.forName(className).newInstance();

        coll.add("123");
        coll.add("abc");
        coll.add("456");
        coll.add("qwe");

        System.out.println(coll);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值