反射

什么是反射

反射机制使在程序运行的状态中,对于任意一个类,都能获取这个类的所有属性和方法;
对于任意一个对象,都能够调用它的任意一个方法和属性。
这种动态获取信息以及动态调用对象的方法的功能称为java语言的反射机制。

反射的作用

  1. 可以实现简单的反编译,获取类中的属性和方法等基本信息, .class->java
  2. 通过反射机制获取类的属性,方法等。
    在使用eclipse时,通过对象引用.的方式,eclipse就会将这个对象中的所有属性和方法展示出来,这个就是利用反射机制。其实反射应用最多的地方就是将来要学习的框架,例如 spring、spring MVC、Mybatis等等。

反射的优点

提高程序的灵活性和扩展性。使用反射机制后,程序在创建对象的时候不用使用new关键字写死在程序中了,而是从配置文件中进行读取,这样可以提高程序的灵活性

Class对象

在类加载器将.class文件读取到内存中的时候,jvm会创建这个.class文件对象,并且只创建一个存放到jvm的方法区内存中,在java.lang包下有个Class类,这个类就是 .class文件的对象类型,任何类在被使用 时,都会创建这个类的Class对象。除此之外,在java.lang.reflect 包下面的类也跟反射有关。

创建一个Person类:

package com.reflect;

public class Person { 
	
	private String name;
	public static int age;
	
	
	
	public Person() {
		super();
		// TODO Auto-generated constructor stub
	}

	public Person(String name) {
		super();
		this.name = name;
	}

	public String getName(int a) {
		return name;
	}

	public void setName(String name,int b) {
		this.name = name;
	}
	
	public void sing(String s,String t) {
		System.out.println("唱歌");
	}
	
	private String pig() {
		return "123";
	}
	

}

获取Person类的Class对象有三种方式

package com.reflect;
/*
 * 获取Person类的Class对象的有三种方式
 */
public class Test01 {

	public static void main(String[] args) throws ClassNotFoundException {
		
		//第一种方式
		//c1引用对象代表整个 Person类
		Class clazz1 = Class.forName("Person");
		
		
		//第二种方式
		//java中每个类型都有class属性
		Class c2 =Person.class;
		
		
		//第三种方式
		//java语言中任何一个java对象都有getClass方法
		
		Person p = new Person();
		Class c3 = p.getClass();
	

	}

}

使用反射类创建Person类的对象

newInstance()

package com.reflect;
/*
 * 使用反射创建类的对象
 */
public class Test02 {

	public static void main(String[] args) throws ClassNotFoundException {
		
		
		try {
			Class clazz = Class.forName("com.reflect.Person");
			Object o = clazz.newInstance();
			System.out.println(o);
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	

	}

}

使用反射获取类的属性

package com.reflect;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

/*
     使用反射获取类中的属性
 */
public class Test03 {

	public static void main(String[] args) throws ClassNotFoundException {
		
		Class c = Class.forName("com.reflect.Person");
		
		
		Field[] field = c.getDeclaredFields();
		
		for(Field f:field) {
			//获取属性变量名
			System.out.println(f.getName()); //name
			
			//获取访问权限修饰符的int值
			System.out.println(f.getModifiers());//2
			
			//将int值转换为访问权限修饰符
			System.out.println(Modifier.toString(f.getModifiers()));//private
			
			//获取属性 类型的class对象
			Class type = f.getType();
			System.out.println(type.getName());//java.lang.String
			
			
			//不带包名的类名
			System.out.println(type.getSimpleName());//String
			
			
			
		}
		

	}

}

使用反射反编译

package com.reflect;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class Test04 {

	public static void main(String[] args) throws ClassNotFoundException {
		
		Class c = Class.forName("com.reflect.Person");
		
		//Class c = Class.forName("java.lang.Integer");

		StringBuilder sb = new StringBuilder(200);
		sb.append(Modifier.toString(c.getModifiers())+" class "+c.getSimpleName()+'\n');
		sb.append("{"+"\n");
		
		
		Field[] field = c.getDeclaredFields();
		for(Field f:field) {
			sb.append(Modifier.toString(f.getModifiers())+"  ");
			sb.append(f.getType().getSimpleName()+"  ");
			sb.append(f.getName()+";");
			sb.append("\n");
		}
		
		sb.append("}");
	
		System.out.println(sb.toString());

	}

}

反射

使用反射获取类中指定属性并赋值

package com.reflect;

import java.lang.reflect.Field;

/*
 * 使用反射获取类中指定的属性并赋值
 */
public class Test05 {

	public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException, InstantiationException, IllegalAccessException {
		
		Class c1 = Class.forName("com.reflect.Person");		
		
		//获取类中指定的属性并赋值
		
		Field f = c1.getDeclaredField("name");
		
		//创建对象
		Object o = c1.newInstance();
		
		
		//从外部打破封装性
		f.setAccessible(true);
		
		//给o对象上的name属性赋值为zhoujian 
		f.set(o, "zhoujian");
		
		//获取o对象上的name属性值
		System.out.println(f.get(o));
		
	
	}

}

使用反射获取类中的方法

下面程序将.class文件中的方法反编译并打印出来。

package com.reflect;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

/*
 	使用反射获取类中的方法
 */
public class Test06 {

	public static void main(String[] args) throws ClassNotFoundException {

		Class c1 = Class.forName("com.reflect.Person");
		
		Method[] method = c1.getDeclaredMethods();
		
		for(Method m:method) {
			
			//方法修饰符
			System.out.print(Modifier.toString(m.getModifiers())+" ");
			
			//方法的返回值类型
			System.out.print(m.getReturnType().getSimpleName()+" ");
			
			//方法名
			System.out.print(m.getName()+"  ");
			
			//方法参数
			Class[] c = m.getParameterTypes();
			
			for(Class p:c) {
				System.out.println(p.getSimpleName());
			}
	
		}
		
	
		
	}

}

使用反射类调用类中的方法

package com.reflect;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/*
 * 使用反射调用类中的方法
 */
public class Test09 {

	public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException {
		
		Class c = Class.forName("com.reflect.Person");
		
		//获取方法
		Method method = c.getDeclaredMethod("setName", String.class,int.class);
		
		//创建对象
		Object o = c.newInstance();
		Object result = method.invoke(o, "a",10);
		System.out.println(result);		


	}

}

使用反射获取构造方法

package com.reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;

/*
 * 使用反射  获取构造方法
 */
public class Test10 {

	public static void main(String[] args) throws ClassNotFoundException {
		
		Class c = Class.forName("com.reflect.Person");
		
		Constructor[] con = c.getConstructors();
		
		for(Constructor c1:con) {
			
			//获取修饰符
			System.out.print(Modifier.toString(c1.getModifiers())+"   ");
			
			//获取方法名
			System.out.print(c1.getName()+"   ");
			
			//获取方法参数
			Class[] Para = c1.getParameterTypes();
			for(Class pa:Para ) {
				System.out.println(pa.getSimpleName()+"   ");
			}
			
			
		}
		
	

	}

}

上一篇:Golang反射机制


下一篇:javascript Reflect