Java 反射机制的个人总结

 

1.反射

1.1 什么是反射

 反射是java语言中的一种机制,通过这种机制可以动态的实例化对象、读写属性、调用方法

 根据提供给的字节码.class文件,拿到该类下面所有的属性和方法,调用

那么私有化的呢?反射最牛B的就是它还可以拿到该类中私有化的东西。

创建一个实体类,多点写属性和方法。

.java  -->  .class

通过.java得到.class ====编译

通过.class得到.java ====反编译(反射)

根据.class文件得到.java。

1.2 类类

   所有狗      狗类 Dog                 狗对象 旺财

   所有猫      猫类 Cat                 猫对象 肥波

   所有类      类类 java.lang.Class     类对象 特定类

1.3  一切反射相关的代码都从获得类对象开始

获得类对象的三种方法 1. Class.forName(完整类名)   2. 类名.class   3. 对象.getClass()

1.2 案例

1.2.1 测试Bean

package test;
/**
 * 学生测试类
 */
public class Student {
	private String sid;

	private String sname;

	public Integer age;

	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.2.2  测试反射方法

package com.test;


import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

import com.entity.Student;
import com.sun.jmx.mbeanserver.ModifiableClassLoaderRepository;

public class TestStudent {
	public static void main(String[] args) {
		try {
			/*
			 * 动态获得类对象
			 */
			//==============第一种获得类对象的方法==========================================
			//第一种获得类对象的方法,通过Class.forName(类路径)获得类对象--常用,可以通过改变path可以改变需要得到的类对象
			String path = "com.entity.Student";
			Class<?> c1 = Class.forName(path);
			
			//===============第二种获得类对象的方法=========================================
			//第二种获得类对象的方法,通过对象.class获得类对象
			//Class c2 =  Student.class;
			//===============第三种获得类对象的方法=========================================
			//第三种获得类对象的方法,通过实例化对象.getClass()获得类对象
			//Class c3 = new Student().getClass();
			//========================================================
			
			/* 
			 * 通过得到的类对象,获得动态对象,对属性进行读和写,进行调用方法
			 */
			
			//=============反射调用无参构造方法创建对象===========================================
			/*
			 * 反射调用无参构造方法创建对象
			 */
//			//省略了一步//通过类对象,获得构造器
//			Constructor con1 = c1.getConstructor();
//			//通过无参构造器获得对象
//			Student stu = (Student)con1.newInstance();
			//=================反射调用有参构造方法创建对象 =======================================
			/*
			 * 反射调用有参构造方法创建对象 
			 */
//			//通过类对象获得构造器
//			Constructor con = c1.getConstructor(String.class);
//			//通过构造器实例化一个对象
//			Student stu2 = (Student)con.newInstance("233");
			//==================反射调用私有化的构造方法======================================
			/*
			 * 反射调用私有化的构造方法
			 */
			//通过类对象获得公开构造器
//			Constructor con2 = c1.getDeclaredConstructor(Integer.class);
//			//将构造器设置为公开的
//			con2.setAccessible(true);
//			//然后就可以调用私有化的构造方法
//			Student stu2 = (Student)con2.newInstance(123);
//			System.out.println(stu2);
			//========================================================
			
			
			/*
			 * 通过反射得到对象的方法
			 */
			//通过反射得到动态对象
//			Constructor con3 =  c1.getConstructor();
//			Student stu = (Student)con3.newInstance();
			//====================通过反射得到对象的方法====================================
			//通过类对象获得方法
//			Method me1 = c1.getMethod("hello");
//			//调用stu的方法(hello)
//			me1.invoke(stu);
			//=====================通过反射得到对象的私有化方法===================================
//			Method me2 = c1.getDeclaredMethod("add", Integer.class,Integer.class);
//			me2.setAccessible(true);
//			System.out.println(me2.invoke(stu,10,20));
			//========================================================
			
			/*
			 *通过反射得到类对象对对象的属性进行读和写 
			 */
			//通过类对象得到构造器
			Constructor<?> con4 = c1.getConstructor();
			//通过构造器得到无参的对象
			Student stu4 = (Student)con4.newInstance();
			//========================================================
			//通过类对象,获得开放的属性
//			Field sid = c1.getDeclaredField("sid");
//			System.out.println(c1.getModifiers());
//			//设置该属性为公开的
//			sid.setAccessible(true);
//			//设置属性stu4中的sid为“123”
//			sid.set(stu4, "123");
//			System.out.println(stu4);
			
			//========================================================
			//	private static final String TEST = "name";
			Field field = c1.getDeclaredField("TEST");
			field.setAccessible(true);
			//返回属性或方法的修饰符,返回的是int类型的 
			/*
			 * 1代表public
			 * 2代表private
			 * 8代表static
			 * 16代表final
			 * 
			 */
			System.out.println(field.getModifiers());
			
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}

}

1.2.3 反射及基本使用方法

package com.test;

import com.entity.Student;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
/**
 * 反射的测试类
 * @author Administrator
 *
 */
public class ReflectTest {
	public static void main(String[] args) throws Exception {
		Class<?> c =  new Student().getClass();		//得到类对象
//		String obj = c.getSimpleName();			//得到对象名
//		Student newInstance = (Student)c.newInstance();  //动态实例化对象
//		String cname = c.getName();		//得到完整类名(全路径名)
		
//-----------------获得某个属性----------------------------------------------
		//得到所有公开的属性名以及属性类型,所在路径,返回所有公开的属性
		Field[] field = c.getFields();   
//		for (Field field2 : field) {
//			System.out.println(field2);
//		}
		
		//通过属性名获得类对象中的该属性的类型以及所在路径,返回当前属性,公开方法
		Field field2 = c.getField("age");	
//		System.out.println(field2);
		
		//返回所有属性,不受访问权限的限制
		Field[] declaredFields = c.getDeclaredFields();
//		for (Field field3 : declaredFields) {
//			System.out.println(field3);
//		}
		
		//通过属性名获得类对象中的该属性的类型以及所在路径,返回当前属性,不受访问权限的限制
		Field field4 = c.getDeclaredField("sid");
		field4.setAccessible(true);				//将属性的访问权限设置问公开的
		Student stu =(Student)c.newInstance();	//实例化对象
		field4.set(stu, "123");					//设置属性值
		String str =  (String) field4.get(stu); //获得属性值
//		System.out.println(str);
//		System.out.println(stu.getSid()+":sid");	//打印输出
		
		//获得元素类型
		Class<?> type = field2.getType();
//		System.out.println(type);
		
//-----------------调用方法----------------------------------------------
		//得到类对象的所有公开方法
		Method[] methods = c.getMethods();
//		for (Method method : methods) {
//			System.out.println(method);
//		}
		
		//得到所有类对象的方法(不受访问修饰符的限制)
		Method[] declaredMethods = c.getDeclaredMethods();
//		for (Method method : declaredMethods) {
//			System.out.println(method);
//		}
		
		//得到类对象的所有构造方法,不受访问修饰符的限制
		Constructor<?>[] declaredConstructors = c.getDeclaredConstructors();
//		for (Constructor<?> constructor : declaredConstructors) {
//			System.out.println(constructor);
//		}
		
		
		//获得指定的公开方法
		Method method = c.getMethod("hello",String.class,Integer.class);
		//获得方法名0.
		String methodName = method.getName();
		//获得方法的返回类型
		Class<?> returnType = method.getReturnType();
		//返回该方法所有的参数类型,返回的是类对象
		Class<?>[] parameterTypes = method.getParameterTypes();
//		for (Class<?> class1 : parameterTypes) {
//			System.out.println(class1+"--");
//		}
		//返回该方法所有的参数类型,返回的是数据类型
		Parameter[] parameters = method.getParameters();
//		for (Parameter parameter : parameters) {
//			System.out.println(parameter);
//		}
		
		//调用方法
		Method method2 = c.getMethod("hello",String.class,Integer.class);
//		method2.invoke(stu,"za",123);
		
		
//-----------------对当前类对象的操作----------------------------------------------
		//获得当前类对象所在的包路径
		Package package1 = c.getPackage();
		//返回当前类对象的父类
		Class<?> superclass = c.getSuperclass();
		//返回当前类对象的接口
		Class<?>[] interfaces = c.getInterfaces();
//		for (Class<?> class1 : interfaces) {
//			System.out.println(class1);
//		}
		
		
		
		
	}
}

1.2.4 获得某个属性的方法

	.getField(String)		//返回某个公开的属性
	.getFields()			//返回所有公开的属性
	.getDeclaredField(String)//返回某个私有属性
	.getDeclaredField()		//返回所有属性(任意访问权限)
	.setAccessible(true)		//为私有属性打开赋值权限
	.set(object, value)		//为某个属性赋值
	.get(obj)				//获得obj对象的某值
	.getModifiers()		//获得修饰符
	.getType()			//获得类型
	.isStatic()
	.isFinal()
	 ……
	.getMethods()			//所有公开	的方法(含继承)
	.getDeclaredMethods()	//所有方法(含私有,但不包含继承)
	.getReturnType()		//获得方法的返回类型
	.getParameterType()	//获得方法的参数
	.getDeclaredMethod(method-name, parameter)
	.invoke(object, value)	//调用方法及参数

	.getDeclaredConstructors()	//获得构造方法
	.getParameterTypes()		//构造方法参数类型
	.getDeclaredConstructor(null)	//获得不带参的构造方法
	.getPackage()				//获得当前类所在包
	.getSuperclass()			//获得父类的class
	.getInterfaces()			//获得接口

	Modifier.isPublic(int)

1.2.5 反射的报错

1.java.lang.IllegalAccessException

原因:在类对象中没找对对于的方法或者访问权限受限

2.java.lang.NoSuchMethodException

原因:没有找到对于的方法,或者不存在

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值