J2EE基础之反射

目录

一:反射

二:类类

三:反射实例化

四:反射动态方法调用

五:反射读取属性


大纲:

 一:反射

1,定义:反射是JAVA语言中一种机制,通过该机制可以动态的实例化对象,读取属性,以及调用方法。

2.作用/为什么要学反射

java的反射机制就是增加程序的灵活性,避免将代码写的太死,使其更灵活。

二:类类

1.什么是类类?

举个通俗易懂的例子:比如旺财是狗类的实例,张三是学生类的实例,而狗类和学生类以及其他所有的类又是类类的实例 所以说类类就是其他类的上一级,其他类就是类类的实例

2.类类的三种获取方式:例:学生类

package com.ljj.reflect;

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());
	}
}

其中包括:三个属性,无参的构造方法,带一个参的公有的构造方法,带两个参的公有的构造方法

无参的公有方法:hello()       带一个参的公有方法 hello(String name)   带两个参的私有方法(integer a,interger b)

 1.如何获取类类

用 类.class

Class clz1=Student.class;

 2.类实例

//2、类实例.getClass()
//		确定本工程有这个类,才可以实例化
		Student stu=new Student();
//		本工程没有这个类,也可以编译通过,但是会在运行期报错
//		Object newInstance = Class.forName("com.ycx.reflect.Student").newInstance();
		Class clz2 = stu.getClass();

3.Class.forName("类的全路径名")

//3、Class.forName("类的全路径名");
		Class clz3 = Class.forName("com.ycx.reflect.Student");

三.反射实例化

什么时候用到?

我们可以通过直接实例来拿到一个类的公开的方法,但是拿不到私有的,此时就需要反射实例化

例:上文中的学生类

* 反射实例化
 1、无参数  共有的构造方法
  2、有参数  共有的构造方法
 3、有多个参数  共有的构造方法
4、私有的构造方法
 

注意:所有的反射皆从获取类类开始!!!

反射中的方法:

1.调用无参的共有的构造方法  同时也是默认的

类类..newInstance();

  2.有参数 共有的构造方法

拿到构造器对象 三个.代表可以传1个或n个参数   拿到一个参数为String的构造器对象,调用类中的方法,括号中填方法参数的类型.class
类类.getConstructor(String.class);

  3、.getDeclaredConstructor();     调用类中的方法,  其中括号里面是填的类型

类类.getDeclaredConstructor(Integer.class);

4.getConstructor与getDeclaredConstructor的区别:

getConstructor只能够获取共有的构造方法,要获取私有的构造器getDeclaredConstructor

但是 很多小伙办在调用了getDeclaredConstructor之后却报错

 解决方法:getDeclaredConstructor 需要设置访问权限

.setAccessible(true);

完整案例:

package com.ljj.reflect;

import java.lang.reflect.Constructor;

/**
 * 反射实例化
 * 1.无参数 共有的构造方法
 * 2.有参数 共有的构造方法
 * 3.有多个参数 共有的构造方法
 * 4.私有的构造方法
 * @author Administrator 刘俊杰
 *下午7:12:41
 */
public class Demo2 {
	public static void main(String[] args) throws Exception, Exception {
		Student stu1 = new Student();
		Student stu2 = new Student("s001");
		Student stu3 = new Student("s001", "fjsdk");
		
		System.out.println("***************以下均为反射方式实例化对象");
		//获取类类
		Class<? extends Student> clz1 = stu1.getClass();
//		默认就是调用无参的 共有的 构造函数
//		1.无参数 共有的构造方法
		Student stu4 = clz1.newInstance();
//		2.有参数 共有的构造方法
//		拿到构造器对象 三个.代表可以传1个或n个参数   拿到一个参数为String的构造器对象
		Constructor<? extends Student> c1 = clz1.getConstructor(String.class);
		Student stu5 = c1.newInstance("s001");
//		3.有多个参数 共有的构造方法 拿到有两个参数的构造器对象
		Constructor<? extends Student> c2 = clz1.getConstructor(String.class,String.class);
		Student stu6 = c2.newInstance("s001","李四");
//		4.私有的构造方法
//		getConstructor只能够获取共有的构造方法,要获取私有的构造器getDeclaredConstructor
		Constructor<? extends Student> c3 = clz1.getDeclaredConstructor(Integer.class);
		//打开访问权限
		c3.setAccessible(true);
		Student stu7 = c3.newInstance(18);
	}
}

 运行结果:参照Student类中的打印结果

 四.反射动态方法调用

1.调用无参的共有方法

调用步骤: 

 1.先拿到类类

 2.拿到方法对象       

 3.调用对应的方法

1.调用无参的共有方法

	    //拿到类类
		Class<Student> clz=Student.class;
		//name:方法名    parameterTypes:方法对应的参数
//		拿到方法对象
		Method m1 = clz.getMethod("hello");
//		1.调用对应的方法
//		第一个参数:那个类实例  第二个参数:方法调用时的实参
//		m1.invoke方法调用的返回值 就是 方法对象本身的返回值 hello方法的返回值
		Object invoke = m1.invoke(clz.newInstance());
		System.out.println(invoke);

结果:

 2.调用一个有参数的共有方法

//		2.调用一个参数的构造方法
		Method m2 = clz.getMethod("hello", String.class);
		Object invoke2 = m2.invoke(clz.newInstance(), "张三");
		System.out.println(invoke2);
//		

结果:

3.调用两个个有参的 私有方法

3调用两个个有参的 私有方法
		Method m3 = clz.getDeclaredMethod("add", Integer.class,Integer.class);
		m3.setAccessible(true);
		Object invoke3 = m3.invoke(clz.newInstance(), 5,5);
		System.out.println(invoke3);

结果:

五: 反射读取属性

需求:读取对象的每一个属性

如果换做我们没有学反射之前来完成这个需求的话,我们可能会这样操作

package com.ljj.reflect;

import java.lang.reflect.Field;

/**
 * @author Administrator 刘俊杰
 *下午5:38:18
 */

public class Demo4 {
	public static void main(String[] args) throws Exception {
		Student stu = new Student("s003", "张三");
		stu.age=20;
//		拿到这个学生所有的属性以及属性值
		System.out.println("age:"+stu.age);
		System.out.println("sname"+stu.getSname());
		System.out.println("sid:"+stu.getSid());
	
	}
}

 读取结果:

 但是现在我们要思考更多的问题:

1.如果我们事先不知道这个类有几个属性呢?

2.假设这个类有几十个属性呢?

所以我们需要使用反射来实现该需求:

代码展示:

package com.ljj.reflect;

import java.lang.reflect.Field;

/**
 * @author Administrator 刘俊杰
 *下午5:38:18
 */

public class Demo4 {
	public static void main(String[] args) throws Exception {
		Student stu = new Student("s003", "张三");
		stu.age=20;
		
//		一切反射从类类开始
		Class<? extends Student> clz = stu.getClass();
//		当前类的所有属性对象
		Field[] fields = clz.getDeclaredFields();
		System.out.println(fields.length);
//		for循环中的f代表每一个属性对象
		for (Field f : fields) {
//			打开访问权限
			f.setAccessible(true);
//			通过属性对象拿到属性名称
			System.out.println(f.getName());
//			拿到当前的属性对象的属性值
			System.out.println(f.get(stu));
		}
	
	}
}

读取结果:

 这样以来我们只需要一个for循环就可以得到所有的属性,无论有多少个属性都可以拿到,代码始终不变

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值