黑马程序员-----------------反射

android培训java培训、期待与您交流!

反射:就是把Java类中的各种成分映射成相应的Java类,通过这种能力可以彻底了解自身的情况为下一步动作做准备。

Java的反射机制实现主要是借助:Class(类对象),Construct(类的构造器对象),Field(属性字段对象),Method (类的方法对象)四个类。

Class:Java中用Java类来描述同一类的事物,描述这一类事物的Java类名就是Class。

如何知道Java类是否属于的同一类事物就可以通过Class类中的方法

由于Class类中没有构造函数,因此不能使用new Class()这种形式来创建Class类对象。

实例化Class类的方式有点特殊,实例化Class类得到得是字节码的形式,得到字节码的三种方式:

1.对象.getClass();new Date().getClass()//得到创建Date对象的字节码

2.类.class;//System.class//得到某个类的字节码

3.forName();//Class.forName("java.util.Date");得到Date类的字节码。

除了类.class获取字节码Java中还有8个基本类型booleanbytecharshortintlongfloatdouble和关键字 void 也表示为 Class 对象。 


package com.leo.blog;

public class ClassDemo {
	public static void main(String[] args) {
		String str = "abc";
		Class cls = str.getClass();
		Class cls1 = String.class;
		Class cls2 = null;
		try {
			 cls2 = Class.forName("java.lang.String");
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		//查看结果三个实例化对象是否是属于同一份字节码
		System.out.println(cls==cls1);//true
		System.out.println(cls==cls2);//true
		
		//检查是一个基本类型字节码
		System.out.println(cls.isPrimitive());//false
		System.out.println(int.class.isPrimitive());//true
		System.out.println(int.class==Integer.class);//false
		System.out.println(int.class==Integer.TYPE);//true
	}
}

只要是在源程序中出现的类型,都具有各自的Class实例对象,由于使用forName的方式,会抛出ClassNotFoundException异常,是为了避免找不到类名。

Construct类

通过反射得到String类型中的构造方法获得字符串中的某个字符。

package com.leo.blog;

import java.lang.reflect.*;
public class ReflectConstructDemo {
	public static void main(String[] args) {
		//创建一个Construct类型对象
		Constructor cons = null;
		
		try {
			cons = String.class.getConstructor(StringBuffer.class);
			String str = (String)cons.newInstance(new StringBuffer("LEO"));
			System.out.println(str.charAt(2));//得到第三个字符:0
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}	
	}
}
注:在获得方法跟调用方法时所用到的实例类需要相同。

Field:通过反射修改类中的属性。

package com.leo.blog;

public class ReflectPoint {

	private int x;
	public int y;
	public String str1 = "ball";
	public String str2 = "basketball";
	public String str3 = "LeoBall";
	public ReflectPoint(int x, int y) {
		super();
		this.x = x;
		this.y = y;
	}
	@Override
	public String toString() {
		return "ReflectPoint [str1=" + str1 + ", str2=" + str2 + ", str3="
				+ str3 + "]";
	}
}
先创建一个类,利用反射机制对类中的属性进行修改。

package com.leo.blog;

import java.lang.reflect.Field;

public class ReflectDemo {

	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception{
		// TODO Auto-generated method stub
		ReflectPoint rp = new ReflectPoint(3,5);
		Field fdY =rp.getClass().getField("y");
		System.out.println(fdY.get(rp));
		
		Field fdX =rp.getClass().getDeclaredField("x");
		fdX.setAccessible(true);
		System.out.println(fdX.get(rp));
		
		System.out.println(rp);
		changeStrValue(rp);
		System.out.println(rp);
		
	}
	public static void changeStrValue(Object obj) throws Exception
	{
		//获取对象所有字段
		Field[] fds = obj.getClass().getFields();
		for (Field fd:fds) {//遍历对象中的所有字段
			//同一份字节码的比较使用==号
			if(fd.getType()==String.class){//比较是否是字符串类型字段
				String oldVal = (String)fd.get(obj);//获取对象的字段的值
				String newVal = oldVal.replace('b','a');//替换字段值中b为a
				fd.set(obj, newVal);//设置对象中字段值
			}
				
		}
	}

}
getDeclaredFields方法可以获取全部的属性包括私有的,getDeclaredField获取的是类中的单个属性,getField跟getFields只能是获取公共的属性。而通过setAccessible可以强制的对私有属性进行修改。

Method类:通过反射得到一个方法。

package com.leo.blog;

import java.lang.reflect.Method;
class MethodPerson
{
	public void play(String str)
	{
		System.out.print(str);
	}
	public static void play(int times)
	{
		System.out.print("玩"+times+"局");
	}
}
public class ReflectMethod {

	/**
	 * @param args
	 */
	public static void main(String[] args)throws Exception {
		// TODO Auto-generated method stub
		MethodPerson mp = new MethodPerson();
		Class c = mp.getClass();
		//创建Method类对象,通过getMethod方法传入方法名,和参数类型
		Method me = c.getMethod("play", int.class);
		//使用invoke去调用类中的paly参数为int类型的方法,
		me.invoke(null, 10);
		
		Method me1 = c.getMethod("play", String.class);
		//使用invoke去调用类中的paly参数为String类型的方法,
		me1.invoke(mp, "BASKETBALL");
	}

}
执行结果就会是:玩10局BASKETBALL


利用 TensorFlow 训练自己的目标识别器。本文内容来自于我的毕业设计,基于 TensorFlow 1.15.0,其他 TensorFlow 版本运行可能存在问题。.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值