java-反射

java-反射

反射介绍:
  • 反射java语言中的一种机制,通过这种机制可以动态的实例化对象、读写属性、调用方法
    百分之90的框架都用到了反射;
类类

反射的相关代码都跟以下几个包相关:

  • java.lang.Class
  • java.lang.reflect.Method
  • java.lang.reflect.Field
  • java.lang.reflect.construct

这是Student.java封装类,下面的案例操作的类

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

获取类对象的方式

  1. Class.forName(“路径名”); jdbc/自定义mvc框架
  2. 类名.class ; 结合泛型做通用分页查询方法会用
  3. 类实例的类实例的getClass()获取 通用的增删改结合泛型使用

代码如下:

package com.hyf.reflect;

public class Demo1 {
   public static void main(String[] args) throws Exception {
	 //1.Class.forName("路径名");  jdbc/自定义mvc框架
	 //  Class stuClz=Class.forName("com.hyf.reflect.Student");
	  
	 //2 类名.class 结合泛型做通用分页查询方法会用
     //  Class stuClz=Student.class;
	   
	 //3.类实例的类实例的getClass()获取
	     Student s=new Student();
	     Class stuClz =s.getClass();
	     System.out.println(stuClz);
}
}

利用反射进行对象实例化

优势:

  1. 能够对未知的对象进行实例化
  2. 能够对私有构造器实例化对象

代码演示:

  • 调用无参构造器去实例化对象
package com.hyf.reflect;

import java.lang.reflect.Constructor;

public class Demo2 {
     public static void main(String[] args) throws Exception{
		
    	Class<Student> stuC=Student.class;
		// newInsTance 这个方法默是默认使用无参构造器去实例化对象
		Student s2 = (Student) stuC.newInstance();
  }
}

输出:


调用有参构造器去实例化对象

下方的代码是调用两个参数的方法,如果只调用一个有参的方法就在(stuC.getConstructor(String.class))只写一个。

package com.hyf.reflect;

import java.lang.reflect.Constructor;

public class Demo2 {
     public static void main(String[] args) throws Exception{
		
    	Class<Student> stuC=Student.class;
		Constructor<Student> constructor =stuC.getConstructor(String.class,String.class);       
    	Student stu2=constructor.newInstance("1","八戒");
  }
}

输出:
在这里插入图片描述


调用私有的构造方法

常会出现的几个错误:

  1. java.lang.NoSuchMethodException: 没用找到匹配的方法
  2. java.lang.IllegalAccessException: 没有权限 解决:.setAccessible(true);打开权限 , 默认为false
    Class com.hyf.reflect.Demo2 can not access a member of class com.hyf.reflect.Student with modifiers “private”
package com.hyf.reflect;

import java.lang.reflect.Constructor;

public class Demo2 {
     public static void main(String[] args) throws Exception{
		
       Class<Student> stuC=Student.class;
	   Constructor<Student> declaredConstructo=stuC.getDeclaredConstructor(Integer.class);
       declaredConstructo.setAccessible(true);// 权限:默认为false
       declaredConstructo.newInstance(18);
	
  }
}

输出:

在这里插入图片描述


动态方法调用

  • 所需的包 java.lang.reflect.Method;

  • 动态调用方法
    Method m;
    m.invoke

package com.hyf.reflect;

import java.lang.reflect.Method;

/**
 * 动态方法调用
 * @author 17628
 */
public class Demo3 {
	public static void main(String[] args) throws Exception {
		Student s = new Student();
		Class sc = s.getClass();

		// 调用无参的方法
		   System.out.println("无参");
		   Method m1 = sc.getDeclaredMethod("hello");
		   m1.invoke(s);
		   System.out.println("");

		// 调用有参的方法
		   System.out.println("有参");
		   Method m2=sc.getDeclaredMethod("hello", String.class);
		   m2.invoke(s, "悟空");
		   System.out.println("");
		   
		// 调用私有方法
		   System.out.println("私有方法");
		   Method m3 = sc.getDeclaredMethod("add", Integer.class, Integer.class);
		   m3.setAccessible(true);
		// Method.invoke的返回值是被动态调用的方法的返回值
		   Object invoke = m3.invoke(s, 12,12);
		   System.out.println(invoke);
	}
}

输出:
在这里插入图片描述


反射读取属性

  • 需要的包: java.lang.reflect.Field

读取单个属性

package com.hyf.reflect;
import java.lang.reflect.Field;

/**
 * 反射读取属性: 自定义标签库。通用分页、自定义mvc 这些需要用到;
 */
public class Demo4 {
	public static void main(String[] args) throws Exception, SecurityException {
		Student s = new Student("110", "黑猫警长");
		s.age = 18;
		Class<? extends Student> sc = s.getClass();

		Field f = sc.getDeclaredField("sname");
		f.setAccessible(true);
		System.out.println(f.get(s));
	}
}

输出:
(小提示:私有的属性也可以读取)
在这里插入图片描述

获取当前Student实例中 s 的所有属性以及属性值

package com.hyf.reflect;

import java.lang.reflect.Field;

public class Demo4 {
	public static void main(String[] args) throws Exception, SecurityException {
		Student s = new Student("110", "黑猫警长");
		s.age = 18;
		Class<? extends Student> sc = s.getClass();
		
		// 获取当前Student实例中 s 的所有属性以及属性值
		Field []  f=sc.getDeclaredFields();
		for (Field field : f) {
			field.setAccessible(true); // 打开权限
			System.out.println(field.getName()+"--"+field.get(s));
		}
	}
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值