Java的反射基础技术

 今天本人给大家讲解一下Java的反射基础技术,如有不对的或者讲的不好的可以多多提出,我会进行相应的更改,先提前感谢提出意见的各位了!!!

  什么是反射?

   反射它是根据字节码文件可以反射出类的信息、字段、方法、构造方法等内容,还可以创建对象调用方法,我们称它为反射技术。

  如何通过反射获取Class对象了?

   它有三种方法,1.通过Class获取类对象

                            2.通过getClass()方法获取类对象

                        3.通过Class.forName(“完整类名”)获取类对象

 

   案例:通过反射获得Class对象的3种方法

Class c1 = ReflectionBasic.class;
Class c2 = new ReflectionBasic().getClass();
Class c3 = Class.forName("reflection.getClassObject.ReflectionBasic");

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

 运行结果:

 

 

 注意:Class.forName()它除了能获取Class对象,还可以将获取的类对象自动加载到JVM虚拟机的内存中去 ,下面案例的运行结果可以看出代码输出的static静态代码块一个泛型的C4和C5对象,可是只有C5输出了static,这就说明了使用Class.forName()可以将类对象加载到JVM虚拟机的内存中去。

  案例:

 //通过输出OtherTest反射对象
 Class<?> c4 = OtherTest.class;
System.out.println("此输出对象是C4==============================="+c4);
Class<?> c5 = Class.forName("reflection.getClassObject.OtherTest");
System.out.println("此输出对象是C5==============================="+c4);
class OtherTest{
static {
System.out.println("你好呀!!!宝宝们!!!");
}
}

   运行结果:

 

 

  获取反射类的信息

  在java.lang.reflect包下有很多反射类信息的类

  反射类的信息

  接口类:

public interface IReflection {
}

  父类:

public class Reflection {
}

  主类:

public class ReflectionInfo extends Reflection implements IReflection {
    public static void main(String[] args) {
        //创建类的对象
        Class<?> c1 = ReflectionInfo.class;
        //获取反射ReflectionInfo类的================================修饰符
        int modifiers = c1.getModifiers();//得到的是一个整数那么我们就需要转换了
        System.out.println(modifiers);
        String sModifiers = Modifier.toString(modifiers);//转换后得到的信息
        System.out.println(sModifiers);
        System.out.println("以上是获取反射ReflectionInfo类的================================修饰符");
        //获取反射ReflectionInfo类的================================完整类名
        String name = c1.getName();
        System.out.println(name);
        //获取反射ReflectionInfo类的================================简易类名
        String simpleName = c1.getSimpleName();
        System.out.println(simpleName);
        System.out.println("以上是获取反射ReflectionInfo类的================================完整类名和简易类名");
        //获取反射ReflectionInfo类的================================完整父类名
        Class<?> superclass = c1.getSuperclass();
        System.out.println(superclass.getSuperclass());
        //获取反射ReflectionInfo类的================================简易父类名
        System.out.println(superclass.getSimpleName());
        System.out.println("以上是获取反射ReflectionInfo类的================================完整父类名和简易父类名");
        //获取反射ReflectionInfo类的================================接口,由于接口可以是多个我们需要通过遍历来输出出来
        Class<?>[] interfaces = c1.getInterfaces();
        if(interfaces.length>0){
            for (int i = 0; i < interfaces.length;i++){
                //获取反射ReflectionInfo类的================================完整接口名
                System.out.println(interfaces[i]);
                //获取反射ReflectionInfo类的================================简易接口名
                System.out.println(interfaces[i].getSimpleName());
            }
        }
    }
}

运行结果:

 

 

通过反射技术访问字段(分private和public修饰)

错误案例:通过getFile()方法得到private属性的值,会报错

public class AccessFiled {
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, InstantiationException {
        //创建Class对象
        Class<?> c1 = Company.class;
        //返回返回的公共字段public
        Field field = c1.getField("name");
        //通过反射技术创建对象实例,默认调用无参构造哦
        Object obj = c1.newInstance();//此方法相当于new一个Company对象
        field.set(obj,"无名公司");  //设置name的字段值
        System.out.println(obj);
        System.out.println(field.get(obj));//输出name的字段值

        //返回返回的公共字段public
        Field fields = c1.getField("id");
        //通过反射技术创建对象实例,默认调用无参构造哦
        field.set(obj,"00001");  //设置name的字段值
        System.out.println(field.get(obj));//输出name的字段值

    }
}
class Company{
    public String name;
    private int id;
}

运行结果:

 

正确案例:使用getDeclaredField()方法得到private修饰的id值,这个是可以得到任意修饰符修饰的字段

   

public class AccessFiled {
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, InstantiationException {
        //创建Class对象
        Class<?> c1 = Company.class;
        //返回返回的公共字段public
        Field field = c1.getField("name");
        //通过反射技术创建对象实例,默认调用无参构造哦
        Object obj = c1.newInstance();//此方法相当于new一个Company对象
        field.set(obj,"无名公司");  //设置name的字段值
        System.out.println(obj);
        System.out.println(field.get(obj));//输出name的字段值

        //返回返回的公共字段public
        Field fields = c1.getDeclaredField("id");
        //通过反射技术创建对象实例,默认调用无参构造哦
        field.set(obj,"00001");  //设置name的字段值
        System.out.println(field.get(obj));//输出name的字段值

    }
}
class Company{
    public String name;
    private int id;
}

运行结果:

 

通过反射技术调用方法

public class CallObject {
    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
        //创建Class对象
        Class<?> c1 = Company.class;
        //反射shou()方法
        Method method = c1.getMethod("show", null);//前面的参数是方法名。后面的是方法的返回值类型
        //通过反射创建实例
        Object obj = c1.newInstance();
        System.out.println("无参==========="+method.invoke(obj,null ));
        System.out.println(obj);
        Method shous = c1.getMethod("shows",String.class);
        shous.invoke(obj,"无名公司");
        //反射shows()方法带(参数列表类型)
        System.out.println("有参==========="+obj);;
    }
}
class Company{
    public String name;
    private int id;

    public void show(){
        System.out.println("show=====方法");
    }
    public void shows(String name){
        System.out.println("shows======方法");
        this.name = name;
    }



    @Override
    public String toString() {
        return "Company{" +
                "name='" + name + '\'' +
                ", id=" + id +
                '}';
    }
}

运行结果:

 

 

  Java的反射基础讲解完毕,又不懂或者不理解的可以在评论区给本人留言,我会及时回复大家的。

posted @ 2020-03-20 00:02  木木~五  阅读(302)  评论(0编辑  收藏  举报