JAVA反射及实践

反射

理论

为什么要学习反射

JAVA反射机制是构建框架技术的基础所在。
灵活掌握Java反射机制,能让代码变得更灵活

为什么已经有new实例化了还要学反射呢?

因为反射实例化能实例化未知的对象帮助开发人员处理未知的网络请求

反射的作用

通过反射可以动态的
实例化对象
读写属性
调用方法

怎么获取类对象

一切反射相关的代码都从获得类对象开始
那么怎么获得类对象呢?
获得类对象有三种方法

1、Class.forName(类的完整路径名)
2、类名.class
3、对象.getClass()

实例化对象

实例化对象分四种

	1、无参公有的实例化
	2、有一个参数的公有构造器实例化
	3、有两个参数的公有构造器实例化
	4、私有的构造器实例化  重点

用途:可以用在调用分页中的查询中

调用方法

调用方法一般分三种

1、无参公有的方法调用
2、有一个参数的方法调用
3、私有的方法调用

用途:可以用在自定义mvc的增强子控制器中

读写属性

读写属性分两种

1、公有的
2、私有的

用途:通用的增删改

实践

效果
在这里插入图片描述

这里用的是学生类做例,学生类代码如下:

package com.wangjuanxia;
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());
	}
}

获取对象

1、Class.forName("")

Class<?> clz = Class.forName("com.wangjuanxia.Student");

2、xxx.class

Class<?> clz =Student.class;

3、对象.getClass
实例化对象,再获取对象

Student stu=new Student();
Class<? extends Student> clz = stu.getClass();

反射实例化对象

共四种

  • 1、无参公有的实例化
	Student stu=new Student();
	Class<? extends Student> clz = stu.getClass();
	Student stu = (Student) clz.newInstance();
	System.out.println(stu);
  • 2、有一个参数的公有构造器实例化,String.class代表参数类型,c.newInstance(“s001”)代表实例化一个sid并赋值s001
Student stu=new Student();
Class<? extends Student> clz = stu.getClass();
Constructor<? extends Student> c = clz.getConstructor(String.class);
Student student = c.newInstance("s001");
System.out.println(student);
  • 3、有两个参数的公有构造器实例化,两个参数都是String类型,赋值,输出
Student stu=new Student();
Class<? extends Student> clz = stu.getClass();
Constructor<? extends Student> c = clz.getConstructor(String.class,String.class);
Student student = c.newInstance("s001","zs");
System.out.println(student.getSid()+"   "+student.getSname());
  • 4、私有的构造器实例化
    这里会出现的错误:
    1
    NoSuchMethodException
    意思:student类中没有Integer为参数的方法
    原因:误将getDeclaredConstructor调用错了,调成了getConstructor或其他方法,
    getConstructor是获取到public修饰的构造方法。
    2
    java.lang.IllegalAccessException
    意思:非法访问
    原因:漏写了c.setAccessible(true);,开放访问private修饰的方法的权限
Student stu=new Student();
Class<? extends Student> clz = stu.getClass();
Constructor<? extends Student> c = clz.getDeclaredConstructor(Integer.class);
c.setAccessible(true);
Student student = c.newInstance(22);
System.out.println(student.age);

调用方法

共三种

  • 1、无参公有的方法调用
    动态被调用的方法,如果该方法是void类型的返回值,那么被invoke的话,结果为null
Student stu=new Student();
Class<? extends Student> clz = stu.getClass();
Method m = clz.getMethod("hello");
Object invoke = m.invoke(stu);
System.out.println(invoke);
  • 2、有一个参数的方法调用
Student stu=new Student();
Class<? extends Student> clz = stu.getClass();
Method m = clz.getMethod("hello", String.class);
Object invoke = m.invoke(stu, "zs");
System.out.println(invoke);
  • 3、私有的方法调用
    如果被动态调用的方法是非void类型的返回值,那么invoke后,返回的就是该被调用的方法的结果
Student stu=new Student();
Class<? extends Student> clz = stu.getClass();
Method m = clz.getDeclaredMethod("add", Integer.class,Integer.class);
m.setAccessible(true);
Object invoke = m.invoke(stu, 12,3);
System.out.println(invoke);

读写属性

共两种

  • 1、公有的,get读属性,set写属性,set(对象,值)
Student stu=new Student();
stu.setSid("1");
stu.setSname("zs");
stu.age=18;
Class<? extends Student> clz = stu.getClass();
Field f3 = clz.getField("age");
f3.set(stu, 16);
System.out.println(f3.get(stu));

  • 2、私有的,注意调用的方法和是否开启权限
Student stu=new Student();
stu.setSid("1");
stu.setSname("zs");
stu.age=18;
Class<? extends Student> clz = stu.getClass();
Field f = clz.getDeclaredField("sname");
f.setAccessible(true);
f.set(stu, "ls");
System.out.println(f.get(stu));
Field f2 = clz.getDeclaredField("sid");
f2.setAccessible(true);
f2.set(stu, "2");
System.out.println(f2.get(stu));

总结

今天的分享到此结束,我是平平无奇秃头小天才,再见ヾ( ̄▽ ̄)ByeBye
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值