不积跬步,无以至千里;不积小流,无以成江海。

 

Java语言基础

 

Java反射

先看一下正向的操作,对这个类进行实例化,再使用这个类对象进行操作。

public class Apple {
	
	private int price;
	public int highprice;
	int lowprice;
	String name;
	
	public int getprice() {
		return price;
	}
	
	public void setprice(int price) {
		this.price = price;
	}
	
	public void sell(){
		System.out.println("All apples are selling!");
	}
	
	private void buy() {
		System.out.println("Buy apples!");
	}

	public static void main(String[] args) throws Exception {
		//正常调用
		Apple apple = new Apple();
		apple.setprice(5);
		System.out.println("apple's price is: " + apple.getprice());

	}

}

  

使用反射机制,先要获取到该类的字节码文件对象(.class)

获取字节码文件对象的三种方式。

Class cls = Class.forName("Testfather.Apple");
Class cls = Apple.class;
Class cls = apple.getClass(); 

1. 通过Class类中的静态方法forName,直接获取到一个类的字节码文件对象,此时该类还是源文件阶段,并没有变为字节码文件。

Class cls = Class.forName("Testfather.Apple"); 

2. 当类被加载成.class文件时,此时Person类变成了.class,在获取该字节码文件对象,也就是获取自己, 该类处于字节码阶段。

Class cls = Apple.class;

3. 通过类的实例获取该类的字节码文件对象,该类处于创建对象阶段。

Class cls = apple.getClass();

  

获取成员变量并使用

获取指定成员变量

//获取指定成员变量price1
//相当于new了一个对象
Object obj = cls.newInstance(); 或者 Apple obj = (Apple)cls.newInstance();
//获取成员变量cls.getField(name),通过name获取指定成员变量
//如果成员变量是私有的使用getDeclaredField(name)
Field fieldprice = cls.getDeclaredField("price1");
//获得属性对象后,由于其是私有的,还要让其打开可见权限
fieldprice.setAccessible(true);
//对成员变量进行赋值操作
fieldprice.setInt(obj, 6);
//获取成员变量的值fieldprice.getInt(obj)
System.out.println(fieldprice.getInt(obj));

  

注意:可以通过构造器实例化对象,当为无参构造器

Constructor constructor = cls.getConstructor();
Object obj = constructor.newInstance();

当是有参构造器

Constructor constructor = cls.getConstructor(int.class, String.class);
Object obj = constructor.newInstance(24, "tutu");

  

获取全部成员变量

//获取全部成员变量
//只能获得public属性
Field[] fields = cls.getFields();
for(Field field: fields){
	System.out.println(field.getName());
}
//私有属性也可以获得
Field[] fields1 = cls.getDeclaredFields();
for(Field field: fields1){
	System.out.print(field.getName() + " ");
}
System.out.println(" ");

  

获得方法并使用

获得指定方法

//调用方法
Method sellmethod = cls.getMethod("sell");
sellmethod.invoke(obj);
/*
 * method.invoke(obj, args)
 *     obj:方法的对象
 *     args:实际的参数值,没有则不填
 */
//调用带参数的方法
Method setpricemethod = cls.getMethod("setprice", int.class);
setpricemethod.invoke(obj, 10);
Method getpricemethod = cls.getMethod("getprice");
System.out.println("apple's price is: " + getpricemethod.invoke(obj));

  

获得所有的方法

//获取所有方法
//getMethods()方法获取的是所有的public的函数,包括父类继承而来的
Method[] methods = cls.getMethods();
for(Method method: methods){
	System.out.print(method.getName() + " ");
}
System.out.println(" ");
//getDeclaredMethods()获取的是所有该类自己声明的方法,不问访问权限
Method[] methods1 = cls.getDeclaredMethods();
for(Method method: methods1){
	System.out.print(method.getName() + " ");
}

  

完整代码:

package Testfather;

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

public class Apple {
	
	private int price;
	private int price1;
	public int highprice;
	int lowprice;
	String name;
	
	public int getprice() {
		return price;
	}
	
	public void setprice(int price) {
		this.price = price;
	}
	
	public void sell(){
		System.out.println("All apples are selling!");
	}
	
	private void buy() {
		System.out.println("Buy apples!");
	}

	public static void main(String[] args) throws Exception {
		//正常调用
		Apple apple = new Apple();
		apple.setprice(5);
		System.out.println("apple's price is: " + apple.getprice());
//		System.out.println(apple.getClass());
		//反射调用
//		Class cls = apple.getClass();
		Class cls = Apple.class;
//		Class cls = Class.forName("Testfather.Apple");
		
		//获取指定成员变量price1
		//相当于new了一个对象
//		Object obj = cls.newInstance();
		//new一个对象
		Apple obj = (Apple)cls.newInstance();
		//获取成员变量cls.getField(name),通过name获取指定成员变量
		//如果成员变量是私有的使用getDeclaredField(name)
		Field fieldprice = cls.getDeclaredField("price1");
		//获得属性对象后,由于其是私有的,还要让其打开可见权限
		fieldprice.setAccessible(true);
		//对成员变量进行赋值操作
		fieldprice.setInt(obj, 6);
		//获取成员变量的值fieldprice.getInt(obj)
		System.out.println(fieldprice.getInt(obj));
		
		//获取全部成员变量
		//只能获得public属性
		Field[] fields = cls.getFields();
		for(Field field: fields){
			System.out.println(field.getName());
		}
		//私有属性也可以获得
		Field[] fields1 = cls.getDeclaredFields();
		for(Field field: fields1){
			System.out.print(field.getName() + " ");
		}
		System.out.println(" ");
		
		//调用方法
		Method sellmethod = cls.getMethod("sell");
		sellmethod.invoke(obj);
		/*
		 * method.invoke(obj, args)
		 *     obj:方法的对象
		 *     args:实际的参数值,没有则不填
		 */
		//调用带参数的方法
		Method setpricemethod = cls.getMethod("setprice", int.class);
		setpricemethod.invoke(obj, 10);
		Method getpricemethod = cls.getMethod("getprice");
		System.out.println("apple's price is: " + getpricemethod.invoke(obj));
		
		//获取所有方法
		//getMethods()方法获取的是所有的public的函数,包括父类继承而来的
		Method[] methods = cls.getMethods();
		for(Method method: methods){
			System.out.print(method.getName() + " ");
		}
		System.out.println(" ");
		//getDeclaredMethods()获取的是所有该类自己声明的方法,不问访问权限
		Method[] methods1 = cls.getDeclaredMethods();
		for(Method method: methods1){
			System.out.print(method.getName() + " ");
		}

	}

}

程序输出:

apple's price is: 5
6
highprice
price price1 highprice lowprice name  
All apples are selling!
apple's price is: 10
main getprice setprice sell wait wait wait equals toString hashCode getClass notify notifyAll  
main getprice setprice sell buy 

  

 

博客借鉴:https://www.cnblogs.com/whgk/p/6122036.html

 

posted on 2019-12-04 16:05  smile学子  阅读(149)  评论(0编辑  收藏  举报