反射-总结

一,什么是反射

在一个程序运行状态时,对于任意一个类,都可知道其属性和方法;对于任意一个对象,都可以调用其属性和方法;而且不仅能拿到,还可以修改它们。这种动态获取信息以及动态调用对象方法的功能称为java语言的反射(reflflection)机制。


二,反射能做什么

1、在日常的第三方应用开发过程中,经常会遇到某个类的某个成员变量、方法或是属性是私有的或是只对系统应用开放,这时候就可以利用Java的反射机制通过反射来获取所需的私有成员或是方法 。

​ 2、反射最重要的用途就是开发各种通用框架,比如在spring中,我们将所有的类Bean交给spring容器管理,无论是 XML配置Bean还是注解配置,当我们从容器中获取Bean来依赖注入时,容器会读取配置,而配置中给的就是类的信息,spring根据这些信息,需要创建那些Bean,spring就动态的创建这些类。

​ 3(有点争议)、当我们在使用 IDE(如 Eclipse\IDEA)时,当我们调用一个类的属性和方法时,一按 (“.”)点号,编译器就会自动列出她的属性或方法,这里就会用到反射。


三,反射的具体实现

1.获取class的三种方式
①Object——>getClass();
②任何数据类型(包括基本数据类型)都有一个”静态“的class属性
③通过class类的静态方法:forName (String className)(常用)

package fanshe;

/*
获取class对象的三种方式:
1.object——>getClass()
2.任何数据类型(包括基础数据类型)都有一个静态的“class”属性
3.通过class类的静态方法:forName(String className)
 */
class Student{
    //私有属性
    private String name="bit";
}
public class fanshe01 {
        public static void main(String[] args) {
            //第一种方式获取Class对象
            Student stu1 = new Student();//这一new 产生一个Student对象,一个Class对象。
            Class stuClass = stu1.getClass();//获取Class对象
            System.out.println(stuClass.getName());//fanshe.Student

            //第二种方式获取Class对象
            Class stuClass2 = Student.class;
            System.out.println(stuClass == stuClass2);//判断第一种方式获取的Class对象和第二种方式获取的是否是同一个
            //true
            //第三种方式获取Class对象
            try {
                Class stuClass3 = Class.forName("fanshe.Student");//注意此字符串必须是真实路径,就是带包名的类路径,包名.类名
                System.out.println(stuClass3 == stuClass2);//判断三种方式是否获取的是同一个Class对象
                //true
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }

        }
    }


通过反射获取构造方法
student类:

package fanshe;
 
public class Student {
	
	//---------------构造方法-------------------
	//(默认的构造方法)
	Student(String str){
		System.out.println("(默认)的构造方法 s = " + str);
	}
	
	//无参构造方法
	public Student(){
		System.out.println("调用了公有、无参构造方法执行了。。。");
	}
	
	//有一个参数的构造方法
	public Student(char name){
		System.out.println("姓名:" + name);
	}
	
	//有多个参数的构造方法
	public Student(String name ,int age){
		System.out.println("姓名:"+name+"年龄:"+ age);//这的执行效率有问题,以后解决。
	}
	
	//受保护的构造方法
	protected Student(boolean n){
		System.out.println("受保护的构造方法 n = " + n);
	}
	
	//私有构造方法
	private Student(int age){
		System.out.println("私有的构造方法   年龄:"+ age);
	}
 
}

共有6个构造方法

测试类:

package fanshe;
 
import java.lang.reflect.Constructor;
 
 
/*
 * 通过Class对象可以获取某个类中的:构造方法、成员变量、成员方法;并访问成员;
 * 
 * 1.获取构造方法:
 * 		1).批量的方法:
 * 			public Constructor[] getConstructors():所有"公有的"构造方法
            public Constructor[] getDeclaredConstructors():获取所有的构造方法(包括私有、受保护、默认、公有)
     
 * 		2).获取单个的方法,并调用:
 * 			public Constructor getConstructor(Class... parameterTypes):获取单个的"公有的"构造方法:
 * 			public Constructor getDeclaredConstructor(Class... parameterTypes):获取"某个构造方法"可以是私有的,或受保护、默认、公有;
 * 		
 * 			调用构造方法:
 * 			Constructor-->newInstance(Object... initargs)
 */
public class Constructors {
 
	public static void main(String[] args) throws Exception {
		//1.加载Class对象
		Class clazz = Class.forName("fanshe.Student");
		
		
		//2.获取所有公有构造方法
		System.out.println("**********************所有公有构造方法*********************************");
		Constructor[] conArray = clazz.getConstructors();
		for(Constructor c : conArray){
			System.out.println(c);
		}
		
		
		System.out.println("************所有的构造方法(包括:私有、受保护、默认、公有)***************");
		conArray = clazz.getDeclaredConstructors();
		for(Constructor c : conArray){
			System.out.println(c);
		}
		
		System.out.println("*****************获取公有、无参的构造方法*******************************");
		Constructor con = clazz.getConstructor(null);
		//1>、因为是无参的构造方法所以类型是一个null,不写也可以:这里需要的是一个参数的类型,切记是类型
		//2>、返回的是描述这个无参构造函数的类对象。
	
		System.out.println("con = " + con);
		//调用构造方法
		Object obj = con.newInstance();
	//	System.out.println("obj = " + obj);
	//	Student stu = (Student)obj;
		
		System.out.println("******************获取私有构造方法,并调用*******************************");
		con = clazz.getDeclaredConstructor(char.class);
		System.out.println(con);
		//调用构造方法
		con.setAccessible(true);//暴力访问(忽略掉访问修饰符)
		obj = con.newInstance('男');
	}
	
}

5、反射优点和缺点

优点:

①对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法

② 增加程序的灵活性和扩展性,降低耦合性,提高自适应能力

③反射已经运用在了很多流行框架如:Struts、Hibernate、Spring 等等。

缺点:

①我们认为反射是一个“自省”的过程,所以在性能上面有性能的问题,一般不建议用在小型程序上,可用到框架当中。

② 反射技术绕过了源代码的技术,因而会带来维护问题。反射代码比相应的直接代码更复杂 。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值