java 反射机制使用

一.Java反射:

   

  (1)定义:在编译时不确定哪个类被加载,而在程序运行时才加载、探知、使用.

  (2)反射常用的Java 类型
Class类—可获取类和类的成员信息 
Field类—可访问类的属性  
Method类—可调用类的方法 
Constructor类—可调用类的构造方法

 (3) 反射的基本步骤
     1.导入java.lang.reflect.* 
     2.获得需要操作的类的Java.lang.Class对象 
     3.调用Class的方法获取Field、Method等对象 

     4.使用反射API进行操作 (设置属性﹑调用方法)

 (4) Class类是Java 反射机制的起源和入口
     1.每个类都有自己的Class 对象
     2.用于获取与类相关的各种信息
     3.提供了获取类信息的相关方法
     4.Class类继承自Object类

 (5) 使用反射

public class TestReflect1 {

	public static void main(String[] args) {
		// 1)先创建对象
		TestReflect1 test = new TestReflect1();
		Class class1 = test.getClass();
		System.out.println(class1);

		// 2)类名.class
		Class class2 = TestReflect1.class;
		System.out.println(class2);

		// 3)常用: Class.forName(包名.类名)
		Class class3 = null;
		try {
			class3 = Class.forName("com.hlx.TestReflect1");
			System.out.println(class3);
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		System.out.println(class3.getDeclaredMethods()[0]);
		System.out.println(class3.getDeclaredMethods()[1]);

		
		
	
		
		//java.lang.IllegalArgumentException: object is not an instance of declaring class
		try {
			
			//*****获得对象**************/
			Object object =class3.newInstance();
			//System.out.println(object);
			
			// 获得方法 第一个方法名: 第二个是:参数的类型
			Method method = class3.getMethod("add",  new Class[]{int.class, int.class,double.class});

			// 通过invoke方法赋值: 第一个参数:对象名;  第二个是:参数值;
			int sum = (int) method.invoke(object, 10, 20,34.57);
			
			System.out.println(sum);

		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	public String show() {
		return "you";
	}

	/**
	 * 两数求和的方法
	 * 
	 * @param num1
	 * @param num2
	 * @return
	 */
	public int add(int num1, int num2,double num3) {
		return (int)(num1 + num2+num3);
	}
	
}
效果:


小结: 

使用反射调用方法的步骤:
      a)要想使用反射,首先需要获得待处理类或对象所对应的Class对象。
      b)获取某个类或某个对象所对应的Class对象的常用的3种方式:
           1)使用Class类的静态方法forName,  => Class.forName(“java.lang.String”)
           2)使用类的.class语法:String.class,=>Class<?> classType = InvokeTester.class;
           3)使用对象的getClass()方法:  =>String s = “aa”;Class<?> clazz=s.getClass();
      c)通过获取的Class对象,产生一个实例 =>Object object =class3.newInstance();
      d)获得想要调用方的Method对象,如Method addMethod = class3.getMethod("add", new Class[]{int.class,int.class});
      e)通过获得的Method对象,在特定实例(对象)上调用方法:Object result = addMethod.invoke(object, new Object[]{1,2});    


/**
 * 客户类
 * 
 * @author Administrator
 *
 */
public class Customer {
	public Long id;
	private String name;
	public int age;
	
	
	

	private Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

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

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	/**
	 * 有参数的构造方法
	 * @param name
	 * @param age
	 */
	public Customer(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	/**
	 * 无参数的构造方法
	 */
	public Customer() {
		super();
		// TODO Auto-generated constructor stub
	}

	@Override
	public String toString() {
		return "Customer [name=" + name + ", age=" + age + "]";
	}
	
	

}
测试:

	public static void main(String[] args) throws Exception {
		
//		调用Constructor的newInstance()方法,适用所有构造方法
		
		//1)Class.forName获得类;
		Class class1 =Class.forName("com.hlx.Customer");
		
		//2)获得构造方法对象 :参数==>类型
		Constructor constructor= class1.getConstructor(String.class,int.class);
		
		//3)给构造方法方法赋值  参数==>对应值
		Object object=constructor.newInstance("熊二",20);
		
		//4)输出数据
		System.out.println((Customer)object);
		
		System.out.println("\n----field------------");
		//获得这个类中所有的属性
		Field[] fields= class1.getDeclaredFields(); //所有的修饰符的public,protected,private...
//		Field[] fields= class1.getFields(); 只能显示public
		for (Field field : fields) {
			System.out.println(field.getName()+"\t"+field.getType()+"\t"+field.getModifiers());

		}
		
		System.out.println("\n----method------------");
		Method[] methods=class1.getDeclaredMethods(); //所有的修饰符的public,protected,private... 当前类中的方法
//		Method[] methods=class1.getMethods(); //只能显示public,不仅是当前类中的,而且父类中的方法也显示
		for (Method method : methods) {
			System.out.println(method.getName()+"\t"+method.getReturnType()+"\t"+method.getModifiers());
		}
		
		
//		调用Field 对象的方法进行取值或赋值操作 
		
		 //给name赋值
		 Field field=class1.getDeclaredField("name");
		 

		 //Exception in thread "main" java.lang.IllegalAccessException: Class com.hlx.TestCustomer can not access a member of class com.hlx.Customer with modifiers "private"
		 //解决:必须给它权限
		 field.setAccessible(true);
		 
		 //设置值: 第一个参数:具体的对象; 第二个参数:name的值
		 field.set(object, "刘芳");
		 
		 //获得name值
		 String string=(String) field.get(object);		 
		 System.out.println(string);
		 
		
		 System.out.println("\n");
	
		 // 获得方法 第一个方法名: 第二个是:参数的类型
		 Method method=class1.getDeclaredMethod("getAge");

		 
		 //创建对象
//		 Object obj=class1.newInstance();
//		 System.out.println(obj);
		 
		 //动态调用方法
		 int age=(int) method.invoke(object);
		 System.out.println(age);

		
	}

效果:


小结: 

   方法一:使用Class的newInstance()方法,仅适用于无参构造方法

//1)Class.forName获得类;
    Class class1 =Class.forName("com.hlx.Customer");
    Object obj=class1.newInstance();

  方法二:调用Constructor的newInstance()方法,适用所有构造方法

	      //1)Class.forName获得类;
		Class class1 =Class.forName("com.hlx.Customer");
		
		//2)获得构造方法对象 :参数==>类型
		Constructor constructor= class1.getConstructor(String.class,int.class);
		
		//3)给构造方法方法赋值  参数==>对应值
		Object object=constructor.newInstance("熊二",20);
Class类是Reflection API 中的核心类,它有以下方法
    –getName():获得类的完整名字。
    –getFields():获得类的public类型的属性。
    –getDeclaredFields():获得类的所有属性。
    –getMethods():获得类的public类型的方法。
    –getDeclaredMethods():获得类的所有方法。
    - getMethod(String name, Class[] parameterTypes):获得类的特定方法,name参数指定方法的名字,parameterTypes参数指定方法的参数类型。
    - getConstructors():获得类的public类型的构造方法。
    - getConstructor(Class[] parameterTypes):获得类的特定构造方法,parameterTypes参数指定构造方法的参数类型。
    - newInstance():通过类的不带参数的构造方法创建这个类的一个对象。
 





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值