栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

学技术ing——反射

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

学技术ing——反射

1、什么是反射?

反射是 Java 程序开发语言的特征之一,它允许运行中的 Java 程序对自身进行检查,或者说“自审”,也有称作“自省”。反射非常强大,它甚至能直接操作程序的私有属性。我们前面学习都有一个概念,被private封装的资源只能类内部访问,外部是不行的,但这个规定被反射赤裸裸的打破了。
反射就像一面镜子,它可以在运行时获取一个类的所有信息,可以获取到任何定义的信息(包括成员变量,成员方法,构造器等),并且可以操纵类的字段、方法、构造器等部分。
那么,作为小白的我怎么理解:
概念:反射是Java的一种机制,让我们可以在运行时获取类的信息;
作用:通过反射,我们可以在程序运行时动态创建对象,还能获取到类的所有信息,比如它的属性、构造器、方法、注解等;

2、利用反射动态创建对象 2.1 获取class对象的三种方式
//创建一个实体类
public class Animal {
    private String name;
    private String sex;
    private int age;

    public Animal(){

    }

    public Animal(String name, String sex, int age) {
        this.name = name;
        this.sex = sex;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Animal{" +
                "name='" + name + ''' +
                ", sex='" + sex + ''' +
                ", age=" + age +
                '}';
    }
}

public class TestAnimal {
    public static void main(String[] args) {
        Animal dog = new Animal("小狗", "公", 2);
        Animal cat = new Animal("小猫", "母", 4);
        
        //1、利用 getClass()方法获取对象的class对象
        Class c1 = dog.getClass();
        Class c2 = cat.getClass();
        System.out.println(c1 == c2);//true

        //2、利用class属性获取字节码文件
        // (类,class:需要输入一个明确的类,任意一个类型都有一个静态的class属性)
        Class c3 = Animal.class;
        System.out.println(c1 == c3);

        //3、利用Class.forName()获取--最常用的方式
        //通过Class类的一个forName(String className)静态方法返回一个Class对象,
        //className必须是全路径名称;
        //Class.forName()有异常:ClassNotFoundException
        try {
            Class c4 = Class.forName("com.etime.entity.Animal");
            System.out.println(c3 == c4);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
}

2.2 动态创建对象

(1)newInstance()创建对象

        //2.2.1 newInstance()创建对象
        try {
            Object obj = c3.newInstance();
            System.out.println(obj.toString());
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

通过Class对象的newInstance()方法来创建Class对象对应类的实例。这个方法是使用Class对象对应类的默认构造器创建对象,这就要求Class对象对应类必须要有默认构造器(无参数的构造方法)。

(2)构造方法创建对象
使用Class对象获取指定的Constructor对象,调用Constructor对象的newInstance()方法来创建Class对象对应类的实例。这个方法可以使用Class对象对应类的任意指定的构造器来创建实例。

//2.2.2 构造方法创建对象
try {
    Constructor constructor = c3.getConstructor(String.class, String.class, int.class);
    Object obj = constructor.newInstance("猪", "母", 2);
    System.out.println(obj.toString());
} catch (NoSuchMethodException e) {
    e.printStackTrace();
} catch (InvocationTargetException e) {
    e.printStackTrace();
} catch (InstantiationException e) {
    e.printStackTrace();
} catch (IllegalAccessException e) {
    e.printStackTrace();
}
三、利用反射调用方法
//获取class对象
			Class c1 = Class.forName("edu.etime.reflex.demo1.Animal");
			//反射创建类的实例
			Animal obj = (Animal) c1.newInstance();		
			obj.setName("人");
			//通过反射获取到method对象
			Method m = c1.getMethod("getName");
			//通过method对象的invoke方法调用方法
			Object o = m.invoke(obj);
			System.out.println(o);
			
四、动态操作属性(调用get,set方法)
//获取class对象
		Class c1 = Class.forName("edu.etime.reflex.demo1.Animal");
		//反射创建类的实例
		Animal obj = (Animal) c1.newInstance();	
		//获取公有属性
		Field[] fileds = c1.getFields();
		for(Field f :fileds){
			System.out.println("公有属性:"+f.getName());
			
		}

		Field[] fileds2 = c1.getDeclaredFields();
		for(Field f :fileds2){
			System.out.println("私有属性:"+f.getName());
		}
		//给属性赋值
		Field[] fileds2 = c1.getDeclaredFields();
		for(Field f :fileds2){
			System.out.println("私有属性:"+f.getName());
			f.setAccessible(true);
			if(f.getType().equals(String.class)){
				f.set(obj, "123");
			}else if(f.getType().equals(int.class)){
				f.set(obj, 123);
			}
		}
		System.out.println(obj.toString());

		//调用get,set方法
		PropertyDescriptor p = new PropertyDescriptor("name",c1);
		//获取写方法
		Method mset = p.getWriteMethod();
		mset.invoke(obj, "xxxxxxx");
		//获取读方法
		Method mget =  p.getReadMethod();
		System.out.println(mget.invoke(obj));
五、反射的应用场景

1、Spring 实例化对象:当程序启动时,Spring 会读取配置文件applicationContext.xml并解析出里面所有的标签实例化到IOC容器中。
2、反射 + 工厂模式:通过反射消除工厂中的多个分支,如果需要生产新的类,无需关注工厂类,工厂类可以应对各种新增的类,反射可以使得程序更加健壮。
3、JDBC连接数据库:使用JDBC连接数据库时,指定连接数据库的驱动类时用到反射加载驱动类

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/936976.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号