反射的应用与理解

反射就是把Java类中的各种成分映射成相应的java类

<代理模式会用到反射,SSH框架会用到框架>

反射使用用中用到的是:字节码(获取类的字节码的三种方式)

例如:People p = new People();

1:Class cls =  Person.class

2:Class cls = p.getClass();

3:Class cls = Class.forName("包名+类名");

字节码的比较,用 “=” 比较,是否为同一份字节码if(f.getType() == String.class){

System.out.println("字节码相同");

}

下面来实战一些关于反射的例题:

 定义一个标准的JavaBean,名叫Person,包含属性name、age。使用反射的方式创建一个实例、调用构造函数初始化name、age,使用反射方式调用setName方法对名称进行设置,不使用setAge方法直接使用反

射方式对age赋值。

定义一个People类

public class People {
	private String name;		//姓名
	private int age;		//年龄
	
	public People() {
		super();
	}
	public People(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	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;
	}
	
}

1>反射类的构造方法: (***********重点:调用构造方法的时候一定要有public修饰)

使用反射的方式调用构造函数初始化name、age

//使用反射的方式调用构造函数初始化name、age
Constructor<People> constructor = People.class.getConstructor(String.class,int.class);
People p1 = (People)constructor.newInstance("江中炼",21);
System.out.println("姓名:"+p1.getName()+"\t年龄:"+p1.getAge());

2>反射类的成员方法:(这代码我调用的是静态方法,null)

//使用反射方式调用setName方法对名称进行设置

//使用反射方式调用setName方法对名称进行设置
People p2 = new People();
Method method = People.class.getMethod("setName", String.class);
method.invoke(p2,"江中炼");
System.out.println("姓名:"+p2.getName());

特殊例子:(method对main方法的另一种应用)(TestArgument类写在Test类中)

class TestArgument {
	public static void main(String[] args) {
		for (String arg : args) {
			System.out.println(arg);
		}
	}	
}

第一种直接获取打印

//main方法赋值!调用另一个TestArgument类的main方法
TestArgument.main(new String[]{"111","222","333"});

第二种反射获取打印

 //反射main方法赋值!
String startClassName = args[0];(类名+包名) 

args[0]表示Test测试类中的args的第一个参数,那怎么写进去呢?

右键Run as --> Run Configurations... -->(Main)旁边的那个:(x)=Arguments --> Program arguments: 里面写下TestArgument类的全面(包名+类名)

(在TestArgument处按下F2就有提示,复制下来就行了),那么args[0]就你刚刚赋的值了

//我们要调用的是main,它的参数是String[],也就是说它只接受字符串类型的数组;
Method mainMethod = Class.forName(startClassName).getMethod("main", String[].class);

***main是静态方法,所以不需要传对象,直接一个null就行

new String[]{"111","222","333"}首先要进行拆箱(为什么要拆箱,跟jdk1.4版本有关),也就是3个参数,但是我要一个数组,所以:(方法1)我要告诉java编译器,我传进来的是就是数组,不需要拆箱了

mainMethod.invoke(null, (Object)new String[]{"111","222","333"});

(方法2)我把它包两层,java编译器拆箱后,剩下的就是一个数组

mainMethod.invoke(null, new Object[]{new String[]{"111","222","333"}});

3>反射类的成员属性:

//使用反射方式对age赋值

People p3 = new People();
//获取所有成员变量
	//Field fieldY = rp1.getClass().getField("age");	//获取所有public修饰的成员
Field field = People.class.getDeclaredField("age");//获取所有(包括private)修饰的成员
//强制访问(暴力反射)针对于私有变量
field.setAccessible(true);
field.set(p3, 21);
System.out.println("年龄:"+p3.getAge());

4>通过数组进行反射

Object obj = null;
obj = new String[]{"a","b","c"}
obj = "xyz";
Class cls = obj.getClass();
//判断obj是否是数组
if(cls.isArray()){
	int len = Array.getLength(obj);
for (int i = 0; i < len; i++) {
	System.out.println(Array.get(obj, i));
}
}else{
	System.out.println(obj);
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java3y

List集合就这么简单【源码剖析】

1894
来自专栏LanceToBigData

JavaSE(八)集合之Set

今天这一篇把之前没有搞懂的TreeSet中的比较搞得非常的清楚,也懂得了它的底层实现。希望博友提意见! 一、Set接口 1.1、Set集合概述   Set集合:...

2075
来自专栏Dato

关于 Integer 值比较的问题

今天刚好遇到这样的问题,别的不说,先上代码 public class TestInteger { public static void main(fi...

2638
来自专栏noteless

JavaSE之Long 详解 Long的方法简介以及用法

java.lang.Long.valueOf(String, int)是借助于parseLong进行转换

1652
来自专栏一直在跳坑然后爬坑

Kotlin之“AbstractMutableList”

打印结果分别为 prefix1:2:3:4:5:6postfix prefix1:2:3:truncatedpostfix

842
来自专栏一枝花算不算浪漫

Java中常见数据结构List之LinkedList

2745
来自专栏Java 源码分析

Java集合框架Collections

1.基本介绍: 集合就是存放对象的,他比数组好的一点就是他一开始不清楚自己长度 容器一般是分为很多种的,很多的容器在一起然后进过断的抽象和抽取就成了一个体系,...

3206
来自专栏云霄雨霁

Java--集合类之Collection与Map

2048
来自专栏Java帮帮-微信公众号-技术文章全总结

Java集合详解【面试+工作】

在说集合前我们不得不说一下数组 数组的作用: 存放一组相同的数据类型(基本或对象)的数据,从而实现对数据的管理 优势:可以快速的通过下标对数组元素进行访问,效率...

4006
来自专栏nnngu

数据结构06 队列

上一篇讲了栈,这一篇要讲的是我们常用的队列,我会从以下几个方面进行总结。 1、什么是队列  2、队列的存储结构 3、队列的常用操作及实现代码 1、什么是队列  ...

2618

扫码关注云+社区