Java中的反射

*传统方式:
   只能静态的创建java对象
* 反射的特点:
  实现了java对象的动态创建.(可以在不确定类的时候动态创建)
* 反射的缺点:
   反射的代码效率低,影响程序性能.
*开发使用:
   反射和传统结合的方式

  

1.反射创建类对象
  第一种方式--->创建类对象
    Class clazz=Class.forName(全限定路径名);

    eg

       Class clazz=Class.forName("pojo.Person");

  第二种方式---->调用底层使用反射封装的方法
    Class cla02=类.class;

    eg

      Class clazz=Person.class;

  


  第三种方式---->调用底层使用反射封装的方法
    Class cla03=对象.getClass();

    eg

    Class cla03=new Person().getClass();

  2.反射调用类的基本信息

    获取类对象的包名---->clazz.getPackage()
    获取类的修饰符----->clazz.getModifiers()
    获取类的名称(全限定)----->clazz.getName()
    获取类的名称(类名)----->clazz.getSimpleName()
    获取类的父类的类对象----->clazz.getSuperclass()

  3.反射获取操作类的属性

  获取类属性
    * getFields() 获取所有的公共字段包括父类 返回Field[]
    * getDeclaredFields() 获取所有声明的字段(不包括父类) 返回Field[]
    * getField("属性名") 获取指定的公共字段包括父类 返回Field
    * getDeclaredField("属性名") 获取指定的声明的字段(不包括父类) 返回Field

  

  操作类属性
    * 操作静态属性
    * 类属性对象.get(null) 返回静态属性的值
    * 类属性对象.set(null,"值") 赋值
    * 操作非静态属性
    * 类属性对象.get(Object obj);
    * 类属性对象.set(Object obj,"值");

public static void operField() throws ClassNotFoundException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, InstantiationException{
		//获取类对象
		Class cla=Class.forName("com.bjsxt.pojo.Student");
		//获取反射类属性
			//获取类及其父类的公共字段
				Field[] fds = cla.getFields();
				for(Field f:fds){
					System.out.println("获取属性名------>"+f.getName());
					System.out.println("获取修饰符------>"+f.getModifiers());
					System.out.println("获取类型------>"+f.getType());//返回的是类型的Class对象
				}
				System.out.println("******************************");
			//获取类声明的所有字段
				Field[] fds2=cla.getDeclaredFields();
				for(Field f:fds2){
					System.out.println("获取属性名----->"+f.getName());
					System.out.println("获取修饰符------>"+f.getModifiers());
					System.out.println("获取类型------>"+f.getType());//返回的是类型的Class对象
				}
				System.out.println("******************************");
			//获取指定的字段
				Field f=cla.getField("pname");//指定获取类及其父类的公共字段
				System.out.println(f.getName());
				Field f2=cla.getDeclaredField("money");//指定获取类的所有字段
				System.out.println(f2.getName());
				Field f3=cla.getSuperclass().getDeclaredField("pname");//指定获取父类声明的字段
				System.out.println(f3.getName());
			//操作字段值
				System.out.println("************操作静态字段**********************");
				//操作静态属性
				Field fs=cla.getDeclaredField("money");
				fs.set(null,2000);
				System.out.println(fs.get(null));
				System.out.println("************操作非静态字段**********************");
				//操作非静态属性
				Field fd=cla.getDeclaredField("sname");
				Object obj=cla.newInstance();
				fd.set(obj, "李四");
				System.out.println(fd.get(obj));	
				//暴力反射操作私有化属性(了解)
				Field fd2=cla.getDeclaredField("ssex");
				fd2.setAccessible(true);//暴力反射,操作私有化属性,不安全
				Object obj2=cla.newInstance();//获取实例化对象
				System.out.println(fd2.get(obj2));
				
	}

  3.反射操作类方法

  操作方法:
    * 获取类对象
    * 获取方法对象
    * getMethods() 获取所有的公共方法包括父类
    * getDeclaredMethods() 获取所有声明的方法不包括父类
    * getMethod(String name,Class...cla) 获取指定的公共方法
    * String name 表示方法名
    * Class...cla 表示方法接收的参数类型的类对象
    * getDeclaredMethod(String name,Class...cla) 获取指定的声明方法
    * String name 表示方法名
    * Class...cla 表示方法接收的参数类型的类对象
  操作方法
    * 静态方法
    * 方法对象.invoke(null,参数值1,参数值2,....);
    * 方法对象.invoke(null,null);
    * 非静态方法
    * Object obj=cla.newInstance();
    * 方法对象.invoke(obj,参数值1,参数值2,....)
    * 方法对象.invoke(obj,null)

//操作方法
	private static void operMethod() throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException {
		//获取类对象
		Class cla=Class.forName("com.bjsxt.pojo.Student");
		//获取类方法对象
			//获取所有的公共方法包括父类
			Method[] ms=cla.getMethods();
			for(Method m:ms){
				System.out.println("获取方法名--->"+m.getName());

			}
			System.out.println("************************************");
			//获取所有声明的方法不包括父类
			Method[] ms2=cla.getDeclaredMethods();
			for(Method m:ms2){
				System.out.println("获取方法名--->"+m.getName());
                                System.out.println("方法的修饰符类型" + m.getModifiers());
                                System.out.println("方法的返回值类型" + m.getReturnType());
        
			}
			//获取指定的公共方法包括父类
				Method m=cla.getMethod("pHi", int.class,String.class);
				System.out.println(m.getReturnType());
			//获取指定的声明的方法,不包括父类
				Method m2=cla.getDeclaredMethod("sHello",null);
				System.out.println(m2.getName());
			//执行方法
				//静态方法
					Method m3=cla.getDeclaredMethod("sHi",String.class);
					m3.invoke(null, "今天学了反射");
				//非静态
					Method m4=cla.getDeclaredMethod("sHi",int.class,String.class);
					m4.invoke(cla.newInstance(), 3,"反射");
	}                                

  4.获取构造器为了创建该类的实例对象

    直接用 cla.newInstance("形参")创建对象

理解:类是对象的抽象,Class也是类,Class类是对类的一直抽象。

原文地址:https://www.cnblogs.com/kilig/p/12116219.html