7月26日JavaSE学习笔记

今日重点:   反射   什么是反射   Class类对象获取方式    Field(get/set)   Method(invoke)  Constructor(newInstance)     内省   BeanInfo   readMethod  writeMethod 


反射

        在程序运行期间,可以动态获取类中定义的属性和方法以及构造方法的机制(思想)的实现。

        反射的核心是Class类  程序中使用的类,每一个都有一个唯一对应的Class对象。

        反射的API:FIeld  Method Constructor(会拼写)。

        面试题:API所在包名:java.lang.reflect

        反射会破坏类的封装性    应用场景不同,通过场景说明,不能直接的说好不好

类的类对象

        java中存储了类的内容,这个内容也因该是对象,java中每一个类都有一个内存,这每一块内存都是一个对象,这些对象记录了这些类中声明了哪些属性和方法以及构造方法,java将这些类抽象为一个class类

        

类对象获取

        Class类的对象是不能new的    
        //获取类的类对象   面试题

        //通过类名获取
		Class clazz=EasyA.class;
		//通过对象获取
		clazz=new EasyA().getClass();
		//通过Class方法的forName方法获取     传入全名
		clazz=Class.forName("com.easy25.EasyColor");
		System.out.println(clazz);

反射获取属性

        java中用来记录类的属性的类叫做Field,使用类对象的getField或getDeclaredField方法获取类的单个属性,或者getFields或getDeclaredFields获得多个属性;注意:getField和getFields只能获取类中public声明的属性,getDeclaredField和getDeclaredFields可以获取所有属性。

        使用:Field实例的get方法可以获取被反射类实例里对应属性具体的值,set方法可以对该种类的实例注入该属性的值,反射访问私有属性注入值时必须先获取访问权限,使用setAccessible传入true即可。

        获取父类属性只能getSuperClass()获取父类类对象,然后获取;获取被子类重写的父类方法也一样。

public static void main(String[] args) throws ClassNotFoundException,  NoSuchFieldException, IllegalArgumentException, IllegalAccessException, IntrospectionException, InvocationTargetException {
		//类的类对象中存储了类中定义的内容  属性  方法  构造方法
		//获取类对象
		Class c=Easy.class;
		c=new Easy().getClass();
		c=Class.forName("com.easy26.Easy");
		
		//获取类中的属性
		//java中用来  记录类的属性  的类叫做Field
		//fName变量指向的对象就是Easy类中的name属性
		Field fName=c.getField("name");
		//获取某一个Easy类的对象的name属性的值
		
		Easy easy=new Easy();
		easy.name="张三";
		System.out.println(easy.name);
		
		//可以获取某一个Easy类的对象的name属性的值
		Object objectName=fName.get(easy);
		System.out.println(objectName);
		//为该种类的实例注入该属性的值
		fName.set(easy, "李四");
		System.out.println(easy.name);
		
		//getField getFileds 只能获取类中public声明的属性
		Field fCode=c.getDeclaredField("code");
		Object objCode=fCode.get(easy);
		System.out.println(objCode);
		//设置code的值
		fCode.set(easy, "9527");
		System.out.println(easy.code);
		
		Field fSex=c.getDeclaredField("sex");
		fSex.set(easy, "塑料袋");
		
		System.out.println(easy.sex);
		//反射访问私有属性  必须先获取访问权限
		Field fAddress=c.getDeclaredField("address");
		fAddress.setAccessible(true);//设置访问权限
		fAddress.set(easy, "USA");
		System.out.println(fAddress.get(easy));
		
		
	}
Modifier判断修饰符

         用Modifier类的方法来判断方法、属性、构造方法被哪些修饰符修饰,步骤:获取要判断的属性的Field实例,获取Field实例的Modifier值,使用Modifier静态方法判断。

//举例判断是否使用static修饰        
Field f=c.getDeclaredField("name");
		int fmod=f.getModifiers();
		boolean bool=Modifier.isStatic(fmod);
		System.out.println(bool);

通过反射获取实例

        举例代码:

package com.easy25;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class Practice extends F{
	public String name;
	private String sex;
	
	
	public String getName() {
		return name;
	}


	public void setName(String name) {
		this.name = name;
	}


	public String getSex() {
		return sex;
	}


	public void setSex(String sex) {
		this.sex = sex;
	}


	@Override
	public String toString() {
		return "Practice [name=" + name + ", sex=" + sex + "]"+"super.salary:"+super.salary;
	}


	public static void main(String[] args) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, IntrospectionException {
		Class clazz=Practice.class;
		Field[] farr=clazz.getDeclaredFields();
		Practice p=(Practice) clazz.newInstance();
		
		 for(Field fitem:farr) {
			System.out.println(fitem.getName());
			if(fitem.getName().equals("name")) {
				fitem.set(p, "张三");
			}else if(fitem.getName().equals("sex")) {
				fitem.set(p, "男");
			}else {
				fitem.set(p, "100");
			}
		}
		Class fclazz=clazz.getSuperclass();
		farr=fclazz.getDeclaredFields();
		for(Field fitem:farr) {
			fitem.set(p, "100");
		}
		System.out.println(p);
		Method[] marr=clazz.getDeclaredMethods();
		for(Method mitem:marr) {
			if(mitem.getName().contains("get")) {
				System.out.println(mitem.getName());
				System.out.println(mitem.invoke(p));
			}
		}
		 
		/*
		 * BeanInfo bif=Introspector.getBeanInfo(clazz);
		PropertyDescriptor[] pd=bif.getPropertyDescriptors();
		for(PropertyDescriptor item:pd) {
			if(!item.getName().equals("class")) {
				System.out.println(item.getName());
				Method read=item.getReadMethod();
				Method write=item.getWriteMethod();
				write.invoke(p, "111");
				System.out.println(read.invoke(p));
			}
		}
		 */
		System.out.println(p);
	}
}
class F{
	public String salary;
	public String getSalary() {
		System.out.println("salary:"+salary);
		return salary;
	}
	public void setSalary(String salary) {
		this.salary = salary;
	}
	
}

反射获取方法

        反射获取方法getMethod(和属性一样,只能获取public方法),其他要用getDeclaredMethod,需要传入方法名,带参需要传入参数列表对应的类对象列表。

        使用:  method.invoke(对象,参数列表);也是可能有返回值,类型是Object

public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		//获取类对象
		Class<Easy> c=Easy.class;
		//加<Easy>j=就不用强转,泛型原因
		Easy easy=c.newInstance();
		//反射获取方法    Method
		//获取public方法,其他要用c.getDeclaredMethod
		Method ma=c.getMethod("methodA");
		//调用方法    对象.方法名()   
		//反射   method.invoke(对象)
		Object b=ma.invoke(easy);
		System.out.println(b);
		//需要传参
		Method mb=c.getMethod("methodB",int.class,int.class);
		mb.invoke(easy, 23,45);
		
	}

反射获取构造方法

        

public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		//反射获取构造方法
		Class<Easy> c=Easy.class;
		c.newInstance();//无参
		//获取无参构造方法
		Constructor<Easy> con=c.getConstructor();
		con.newInstance();
		//带参构造方法
		con=c.getConstructor(String.class);
		con.newInstance("张三");
	}

内省

        也是通过反射实现的     内省不会破坏封装性:底层是通过反射实现,内省获取属性的读方法和写方法(getter/setter)来获取和设置属性的内容,不会破坏类的封装性。

        使用步骤:获取类对象对应的BeanInfo对象,调用getPropertyDescriptors方法获取属性描述器数组PropertyDescriptor[],调用数组内每一个PropertyDescriptor的getReadMethod/getWriteMethod方法获取读写的Method对象,使用invoke写入,read.invoke方法调用的是类的getter方法,write.invoke方法调用的是类的setter方法

        内省可以直接获得本类和父类的所有getter和setter方法,不需要获取父类类对象然后注入

        Class c=Easy.class;        
        //获取BeanInfo
		BeanInfo bi=Introspector.getBeanInfo(c);
		//获取属性的写的方法和读的方法    setter/getter
		PropertyDescriptor[] pds=bi.getPropertyDescriptors();
		
		String pname=pds[0].getName();//获取属性名字
		System.out.println(pname);
		
		//这里要明确是什么类型传入什么类型参数
		Method read=pds[0].getReadMethod();//该属性对应的getter方法
		Method write=pds[0].getWriteMethod();//该属性对应的Setter方法
		//obj.setName("");
		//write.invoke(obj,"");

		write.invoke(easy, "张三");

        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值