反射的实例化及方法调用

思维导图~~~

一、什么是反射

        反射是java语言的一种机制,利用反射机制动态的实例化对象(构造函数)、读写属性、调用方法。
 

二、类类

1、如何得到类对象

一切反射相关的代码都从获得类对象开始;

2、三种获取方式

(1)、Class.forName(全限定名/全路径名)(最常用);

(2)、类名.class;

(3)、对象名.getClass();

      在写有参构造的时候顺便加一个无参构造;因为在很多框架的底层是通过无参构造去对类进行实例化的;

没有无参构造会报以下错误:

Student类:(所有代码中所用的)

package com.mwy.fs;
public class Student {
	private String sid;
	private String sname;
	public Integer age;
	static{
		System.out.println("加载进jvm中!");
	}
	public Student() {
		super();
		System.out.println("调用无参构造方法创建了一个学生对象");
	}
	public Student(String sid) {
		super();
		this.sid = sid;
		System.out.println("调用带一个参数的构造方法创建了一个学生对象");
	}
	public Student(String sid, String sname) {
		super();
		this.sid = sid;
		this.sname = sname;
		System.out.println("调用带二个参数的构造方法创建了一个学生对象");
	}
	@SuppressWarnings("unused")
	private Student(Integer age) {
		System.out.println("调用Student类私有的构造方法创建一个学生对象");
		this.age = age;
	}
	public String getSid() {
		return sid;
	}
	public void setSid(String sid) {
		this.sid = sid;
	}
	public String getSname() {
		return sname;
	}
	public void setSname(String sname) {
		this.sname = sname;
	}
	public void hello() {
		System.out.println("你好!我是" + this.sname);
	}
	public void hello(String name) {
		System.out.println(name + "你好!我是" + this.sname);
	}
	@SuppressWarnings("unused")
	private Integer add(Integer a, Integer b) {
		return new Integer(a.intValue() + b.intValue());
	}
}

三种获取方式:

package com.mwy.fs;
/**
 * 获取类类的类对象的三种方式
 * 1、Class.forName
 * 2、类.class
 * 3、类类的类对象的类实例.getClass();
 */
public class Test_1 {
	public static void main(String[] args) throws Exception {
		//1、Class.forName
		Class<Student> stuCla = (Class<Student>) Class.forName("com.mwy.fs.Student");
		//2、Student.class 会用于:通用查询
		Class stuCla1=Student.class;
		//3、会用于:通用增删改
		Class stuCla2=new Student().getClass();
	}
}

注意:ClassNotFoundException(类名错|少jar包);同一类的、类对象只会创建一个 。

三、反射实例化

1、getConstructor:获取单个公有构造方法;

2、getDeclaredConstructor:获取单个构造方法(包括私有、受保护、默认、公有);

3、getConstrutors();  :获取所有的公有构造方法

4、getDeclaredConstrutors();   :获取所有的构造方法(包括私有、受保护、默认、公有)

5、newInstance

//1、Class.forName
        Class<Student> stuCla = (Class<Student>) Class.forName("com.mwy.fs.Student");、

//实例化
        Student stu = stuCla.newInstance();

1、getDeclaredConstructor与getConstructor的区别

(1)getConstructor() ;反射调用有参构造

        //反射调用有参构造
		//括号里面放要调的有参构造的参数类型
		Constructor<Student> c = stuCla.getConstructor(String.class);
		//实例化
		Student s = c.newInstance("s001");
		//括号里面放要调的有参构造的参数类型
		Constructor<Student> c1 = stuCla.getConstructor(String.class,String.class);
		//实例化
		Student s1 = c1.newInstance("s001","zs");

(2)调用私有化(公开)的方法 ;getDeclaredConstructor();

        //getDeclaredConstructor:可以获取到私有的构造器,以及公共的构造器
		//调用私有化的方法
		//括号里面放要调的有参构造的参数类型
		Constructor<Student> c2 = stuCla.getDeclaredConstructor(Integer.class);
		//打开访问权限
		c2.setAccessible(true);
		//实例化
		Student s2 = c2.newInstance(18);

(3)setAccessible():打开访问权限

①、当私有化方法用getConstructor();时

②、调用getDeclaredConstructor();记得打开权限;不然会出现以下错误:

四、反射动态方法调用

1、getMethod();    :获取单个公有方法

2、getDeclaredMethod();   :获取单个方法(包括私有、受保护、默认、公有)

3、getMethods();       :获取所有公有方法

4、getDeclaredMethods();    :获取所有的方法(包括私有、受保护、默认、公有)

调用hello方法,方法无参;

        //1、Class.forName
		Class<Student> stuCla = (Class<Student>) Class.forName("com.mwy.fs.Student");
		//实例化
		Student s = stuCla.newInstance();
		//调用hello方法,方法无参;
		 Method m = stuCla.getDeclaredMethod("hello");
		//执行;invoke参数1:类实例,在这里指的是Student类实例;
		 //参数2:当前被调用的方法,传递的参数值;
		 //invoke的返回值,就是被反射调用的方法的返回值;如果被调用的方法是void,那么返回null;
		System.out.println( m.invoke(s));

调用hello方法,方法有参;参数放有参构造的参数类型 

       //调用hello方法,方法有参;参数放有参构造的参数类型
		Method m1 = stuCla.getDeclaredMethod("hello",String.class);
		System.out.println( m1.invoke(s,"mwy"));
		
		//调用私有化hello方法,方法有参;参数放有参构造的参数类型
		Method m2 = stuCla.getDeclaredMethod("add",Integer.class,Integer.class);
		//打开访问权限
		m2.setAccessible(true);
		System.out.println( m2.invoke(s,10,10));

结果为: 

五、反射读写属性

Field f = stuCla.getDeclaredField("sname");    //sname:属性名

 1、getDeclaredField(“属性名”);    获取单个属性(私有、公有、受保护、默认、静态)  

 2、getDeclaredFields();    获取所有属性(私有、公有、受保护、默认、静态)

 3、getName();    获取属性名

 4、getType();       获取属性类型 

 5、getModifiers();      获取属性访问修饰符 

 6、set(Object,Object);     设置属性值,参数1:要设置属性所在对象;参数2:要设置的值

 7、get(Object);   获取属性值,参数:要获取属性值的对象      

        //1、Class.forName
		Class<Student> stuCla = (Class<Student>) Class.forName("com.mwy.fs.Student");
		//实例化
		Student s = stuCla.newInstance();
		//拿到Student的sname
		Field f = stuCla.getDeclaredField("sname");
		//打开访问权限
		f.setAccessible(true);
		//反射写属性
		//第一个:给类实例放入;第二个:给sname的属性设置值
		f.set(s, "mwy");
		//oop的读属性
		System.out.println(s.getSname());
		//反射读属性
		System.out.println(f.get(s));

 例题:比较OOP与反射读取属性值得方式

        Student stu=new Student("soo2","ls");
		stu.age=18;
		System.out.println(stu.getSid());
		System.out.println(stu.getSname());
		System.out.println(stu.age);
		System.out.println("----------");
		//反射获取该对象所有属性值
		Field[] field = stuCla.getDeclaredFields();
		for (Field ff : field) {
			ff.setAccessible(true);//打开权限
			System.out.println(ff.getName()+":"+ff.get(stu));
		}

结果: 反射更便捷;

今天到此结束了哦~~~ 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值