Java反射总结

一、反射的概念

       反射机制通过获得JVM中的字节码文件来获得类的相关信息。

二、Class类

       Class类用来描述一切的类和接口,枚举是一种类,注解是一种接口。

       Class实例:对应着JVM中的一份字节码。

  Class实例化方法:

     1.类名.class(就是一份字节码)
     2.Class.forName(String className);根据一个类的全限定名来构建Class对象
     3.每一个对象多有getClass()方法:obj.getClass();返回对象的真实类型


三、九大内置对象

        byte,short,int,long,char,float,double,boolean ,void关键字
        上述8种类型和void关键字,都有class属性.
表示int的Class对象:  Class clz = int.class;
表示boolean的Class对象:  boolean.class;

四、数组的Class实例

      Class clz = String[].class;//此时clz表示就是一个String类型的一维数组类型
      所有具有相同元素类型和维数的数组才共享同一份字节码(Class对象);

五、获得构造器

通过字节码获得构造器的四种方法

                      clz2.getConstructors();
                      clz2.getDeclaredConstructors();

                     clz2.getConstructor(参数的字节码实例);
                     clz2.getDeclaredConstructor(参数的字节码实例);

六、创建对象

  Class<User> userClass = (Class<User>) Class.forName("construct.User");
        //2.获得要调用的指定构造器(通过参数列表)
        Constructor<User> con = userClass.getDeclaredConstructor();
        //3.调用newInstance方法获得对象
        User u = con.newInstance();
        con = userClass.getConstructor(String.class);
        u = con.newInstance("Tom");
        
        //在调用私有型构造方法前,要设置方法的可访问性为true
        /*对于公共成员、默认(打包)访问成员、受保护成员和私有成员,在分别使用 Field、Method 或 Constructor 对象来设置或获取字段、调用方法,或者创建和初始化类的新实例的时候,会执行访问检查。*/
        con = userClass.getDeclaredConstructor(String.class,int.class);
        con.setAccessible(true);
        u = con.newInstance("Tom",22);
七、获取类中的方法

package construct;

import java.lang.reflect.Method;

/**
 * 获得类中方法的步骤:
 * 1、获得类的字节码
 * 2、通过getMothod等方法获得方法体。
 * 
 * Class类中有关获得Method的常用方法:
 * 1、public Method[] getMethods():
 *    返回一个Method对象数组,包括类和接口(包括超类和超接口中声明的)中的所有公共方法
 * 2、public Method[] getDeclaredMethods():
                返回一个Method对象数组,包含类和接口(不包括超类)中的所有方法
 * 
 * 
 * 3、public Method getMethod(String name,
                        Class<?>... parameterTypes)
         返回一个Method对象,包含类和接口(包括超类)中的匹配的方法               
     	参数:
		name - 方法名
		parameterTypes - 参数列表
		返回:
		与指定的 name 和 parameterTypes 匹配的 Method 对象 
		
	4、public Method getDeclaredMethod(String name,
                                Class<?>... parameterTypes)
                       参数:
		name - 方法名
		parameterTypes - 参数列表
		返回:
		与指定的 name 和 parameterTypes 匹配的 Method 对象 
                                	                    
 * */


public class GetMothodDemo {

	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
       getMethods();
       System.out.println("-------------------");
       getOneMethod();
	}
	public static void getMethods() throws Exception{
		Class cla = Class.forName("construct.User");
		Method[] methods = cla.getMethods();
		for (Method m : methods) {
			System.out.println(m);
		}
		System.out.println("----------------------------");
		methods = cla.getDeclaredMethods();
		for (Method m : methods) {
			System.out.println(m);
		}
	}
    public static void getOneMethod() throws Exception{
    	Class cla = User.class;
    	Method method = cla.getMethod("sayHi");
    	method = cla.getMethod("toString");
    	System.out.println(method);
    	method = cla.getDeclaredMethod("sayHello");
    	System.out.println(method);
    	
    }
}
八、调用方法

package construct;

import java.lang.reflect.Method;

/**
 * 方法调用的步骤:
 * 1、获得字节码
 * 2、获得方法
 * 3、调用方法
 *    Method类中,invoke方法用于实现方法调用
 *    public Object invoke(Object obj,
 *                    Object... args)
 *      obj - 从中调用底层方法的对象
 *	    args - 用于方法调用的参数              
 * 对于静态方法的调用:
 *  如果底层方法是静态的,那么可以忽略指定的 obj 参数。该参数可以为 null。
 *  
 * 对于可变参数列表:
 *   方法的类型为对应的数组类型,
 *   个别参数被自动解包,以便与基本形参相匹配,所以,使用Object数组进行封包。
 *       
 * */
public class MethodInvokeDemo {

	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
        Class clz = User.class;
        Method say = clz.getMethod("sayHi");
        say.invoke(clz.newInstance());
        say = clz.getDeclaredMethod("sayHello");
        say.setAccessible(true);
        say.invoke(clz.newInstance());
        System.out.println("-----------------------");
        clz = MethodInvokeDemo.class;
        Method staticMethod = clz.getMethod("hello");
        staticMethod.invoke(null);
        System.out.println("-----------------------");
        staticMethod = clz.getMethod("hello2", String[].class);
        staticMethod.invoke(null,new Object[]{new String[]{"TOM","Jerry"}});
        
	}
	public static void hello(){
		System.out.println("hello");
	}
    public static void hello2(String ...strings){
    	for (String string : strings) {
			System.out.println(string);
		}
    }
}
九、字段操作

package construct;

import java.lang.reflect.Field;

/**
 * 获得字段的步骤:
 * 1、获得字节码
 * 2、从字节码中获得字段
 * 常用方法:
 * public Field[] getFields():获得所有公有字段,包括继承字段
 * public Field getField(String name):获得指定的公有字段
 * public Field[] getDeclaredFields():获得所有字段,不包括继承字段
 * public Field getDeclaredField(String name):获得指定字段
 * 
 * 使用字段:
 * 
 * 为指定字段设置值和获取值。
 * 设置值:
 * 使用Field类中的相关set方法
 * 
 * 获取值:get方法
 *
 * 
 * */

class Emp{
	public String name = "Jerry";
	private int age;
	private boolean sex;
	@Override
	public String toString() {
		return "Emp [name=" + name + ", age=" + age + ", sex=" + sex + "]";
	}
	
}
public class GetFilderDemo {

	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
        //   getFileds();
        //   getFiled();
		setValue();
		getValue();
	}
	public static void getFiled() throws Exception{
		Class clz = Emp.class;
		Field field = clz.getField("name");
		System.out.println(field);
	}
	public static void getFileds(){
		Class clz = Emp.class;
		Field[] fields = clz.getFields();
		for (Field field : fields) {
			System.out.println(field);
		}
		System.out.println("---------------");
		fields = clz.getDeclaredFields();
		for (Field field : fields) {
			System.out.println(field);
		}
	}
	public static void setValue() throws Exception {
		Class clz = Emp.class;
		Field field = clz.getField("name");
		Object emp = clz.newInstance();
		field.set(emp, "Tom");
		System.out.println(emp);
	}
	public static void getValue() throws Exception {
		Class clz = Emp.class; 
		Field field = clz.getField("name");
		Object obj = clz.newInstance();
		String name = (String) field.get(obj);
		System.out.println(name);
	}

}





                     




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值