浅谈java反射问题

首先我们需要知道什么是反射?反射是用来干什么的。

答:一个类有多个组成部分,反射就是加载类,并解析出类的各个组成部分。一般在框架中才会使用反射技术。反射技术是一种打破了常规的私有方法不能被外部访问的特例。但是调用私有方法或字段必须用setAccessible(true)方法,即暴力反射。

接下来看代码部分来讲解反射的一些常用的用法。反射函数,反射字段,反射技术创建对象。

首先是一个要发射的类Person,代码如下

package Day01;

import java.util.List;

public class Person {
	private String name="zhangsan";
	private int age;
	public Person(){
		System.out.println("无参构造方法被调用了");
	}
	public Person(String name,int age){
		this.name=name;
		this.age=age;
		System.out.println("name="+name+"age="+age);
	}
	private Person(List list){
		System.out.println("list方法被调用了");
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public void sing(){
		System.out.println("sing");
	}
	public void talk(String name,int age){
		System.out.println("姓名:"+name+"年龄:"+age);
	}
	public static void  aa(int a){
		System.out.println("aa"+a);
	}
	public static void main(String[] args) {
		System.out.println("main");
	}

}

接下来是一个类Reflect主要用来讲解反射的基础

package Day01;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import org.junit.Test;

public class Reflect {
	/**
	 * 
	 * @用反射构造函数创建对象
	 */
	@Test
	public void test1() throws Exception {
		// 1.加载类方式1
		Class clazz1 = Class.forName("Day01.Person");// 包名.类名

		// 2.加载类方式2
		Class clazz2 = new Person().getClass();
		// 3.加载类方式3
		Class clazz3 = Person.class;

		// 反射构造函数public Person()
		Constructor c = clazz1.getConstructor(null);
		Person p = (Person) c.newInstance(null);
		System.out.println(p);

	}

	@Test
	public void test2() throws Exception {
		Class clazz = Class.forName("Day01.Person");
		// 反射构造函数public Person(String name,int age)
		Constructor c = clazz.getConstructor(String.class, int.class);
		c.newInstance("李四", 18);

	}

	@Test
	public void test3() throws Exception {
		Class clazz = Class.forName("Day01.Person");
		// 反射构造函数private Person(List list)
		// Constructor c=clazz.getConstructor(List.class);错误,因为该方法为私有的,所以要用getDeclaredConstructor();
		Constructor c = clazz.getDeclaredConstructor(List.class);
		c.setAccessible(true);// 暴力反射,可以获得私有型数据,如果没有这句话将会抛出java.lang.IllegalAccessException异常
		Person p = (Person) c.newInstance(new ArrayList());
	}

	@Test
	public void test4() throws Exception {
		Class clazz = Class.forName("Day01.Person");
		Person p = (Person) clazz.newInstance();// 实现原理就是调用了无参构造方法。等效于test1()
	}

	/**
	 * 反射类的方法
	 */
	@Test
	public void test5() throws Exception {
		Person p = new Person();
		Class clazz = Class.forName("Day01.Person");
		// 反射公共无参方法public void sing()
		Method m = clazz.getMethod("sing", null);// 第一个参数书方法名,第二个参数是参数类型
		m.invoke(p);// 调用方法 第一个参数为 对象,后面可变参数为形参。
	}

	@Test
	public void test6() throws Exception {
		Person p = new Person();
		Class clazz = Class.forName("Day01.Person");
		// 反射public void talk(String name,int age)
		Method m = clazz.getMethod("talk", String.class, int.class);// 第一个参数书方法名,第二个参数是参数类型
		m.invoke(p, "张三", 18);// 调用方法 第一个参数为 对象,后面可变参数为形参。
	}

	@Test
	public void test7() throws Exception {
		Class clazz = Class.forName("Day01.Person");
		// 反射public static void aa(int a)静态
		Method m = clazz.getMethod("aa", int.class);// 第一个参数书方法名,第二个参数是参数类型
		m.invoke(null, 18);// 静态方法不需要对象,所以传null
	}

	@Test
	public void test8() throws Exception {
		Class clazz = Class.forName("Day01.Person");
		// 反射public static void main(String[] args) ;与其他不一样,特殊
		Method m = clazz.getMethod("main", String[].class);
		m.invoke(null, new Object[] { new String[] { "aa", "bb" } });// 由于jdk1.4之前数组会才分,所以应该让他拆分之后仍为数组
		// m.invoke(null, (Object)new String[]{"aa","bb"});//此法也行 欺骗虚拟机不拆分即可。
	}

	/**
	 * 反射类的字段
	 * 
	 */
	@Test
	public void test9() throws Exception {
		Class clazz = Class.forName("Day01.Person");
		Field field = clazz.getDeclaredField("name");// private String
		// name="zhangsan";
		Class type = field.getType();// 获得字段类型
		System.out.println(type);
		Person p = new Person();
		field.setAccessible(true);// 访问私有属性的字段或者方法要暴力破解
		if (type.equals(String.class)) {
			String value = (String) field.get(p);// 获取字段值
			System.out.println(value);
		}
		/*
		 * else if(){ 其他一些判断之类的 }
		 */

	}
}



  • 4
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值