Java反射之四大核心类

一、反射
1.反射指的是对象的反向处理操作,是根据对象来取得对象的来源信息。
2.类的对象的三种产生模式
(1)任何类的对象可以通过Object类中的getClass()方法取得Class类对象。
(2)"类.class":直接根据某个具体的类来取得Class类的对象。

(3)使用Class类提供的方法:

public static Class<?> forName(String className) throws ClassNotFoundException

如:

public class Test {
	public static void main(String[] args) throws ClassNotFoundException {
		Date date = new Date();
		System.out.println(date.getClass());	//(1)
		System.out.println(Date.class);	    //(2)
		System.out.println(Class.forName("java.util.Date"));	//(3)
	}
}
3.利用反射进行实例化对象

        在Class类中定义有如下方法:

public T newInstance() throws InstantiationException, IllegalAccessException

如:

public class Test{
	public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
		Date date = new Date();
		Class<?> class1 = date.getClass();
		Class<?> class2 = Date.class;
		Class<?> class3 = Class.forName("java.util.Date");
		Object object1 = class1.newInstance();
		Object object2 = class2.newInstance();
		Object object3 = class3.newInstance();
		System.out.println(object1);
		System.out.println(object2);
		System.out.println(object3);
	}
}
二、反射与类操作

反射操作形式


1.取得父类信息

(1)取得类的包名称:

public Package getPackage()

(2)取得父类的Class对象:

public native Class<? super T> getSuperclass()

(3)取得实现的父接口:

public Class<?>[] getInterfaces()

如:

interface IFruit{}
interface IMessage{}
class Father{}
class CLS extends Father implements IFruit,IMessage {}
public class Test{
	public static void main(String[] args) {
		Class<?> class1 = CLS.class;
		System.out.println(class1.getPackage());	//取得包名称
		System.out.println(class1.getSuperclass());	    //取得父类名称
		Class<?>[] classes = class1.getInterfaces();    //取得实现的父接口
		for (Class<?> class2 : classes) {
			System.out.println(class2);
		}
	}
}
2.反射调用构造

(1)取得指定参数类型的构造:

public Constructor<T> getConstructor(Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException

(2)取得类中的所有构造:

public Constructor<?>[] getConstructors() throws SecurityException

如:取得类中的所有构造信息

class Person{
	public Person() {}
	public Person(String name) {}
	public Person(String name,int age) {}
}
public class Test{
	public static void main(String[] args) {
		Class<?> class1 = Person.class;
		Constructor<?>[] constructor = class1.getConstructors();
		for (Constructor<?> constructor2 : constructor) {
			System.out.println(constructor2);
		}
	}
}

如:通过Constructor类实例化对象

class Person{
	private String name;
	private int age;
	public Person(String name,int age) {
		this.name = name;
		this.age = age;
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}
}
public class Test{
	public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		Class<?> class1 = Person.class;
		Constructor<?> constructor = class1.getConstructor(String.class,int.class);
		System.out.println(constructor.newInstance("小明",10));
	}
}
注意:在定义简单Java类的时候一定要保留一个无参构造,Class类通过反射实例化对象的时候,只能够调用类中的无参构造。如果现在类中没有无参构造,则无法使用Class类调用,只能通过明确的构造调用实例化处理。
3.反射调用普通方法

取得全部普通方法:

public Method[] getMethods() throws SecurityException

取得指定普通方法:

public Method getMethod(String name, Class<?>... parameterTypes)

调用:

public Object invoke(Object obj, Object... args)throws IllegalAccessException, IllegalArgumentException,InvocationTargetException

如:

class Person{
	private String name;
	private int age;
	public Person() {}
	public Person(String name,int age) {
		this.name = name;
		this.age = age;
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}
	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;
	}
}
public class Test{
	public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		Class<?> class1 = Person.class;
		Method[] methods = class1.getMethods();    //获取一个类的全部普通方法
		for (Method method : methods) {
			System.out.println(method);
		}
		System.out.println("******************************************");    //分割线
		//任何时候调用类中的普通方法都必须有实例化对象
		Object object = class1.newInstance();
		//取得setName这个方法的实例化对象,设置方法名称与参数类型
		Method Name = class1.getMethod("setName", String.class);
		//通过Method类对象调用指定的方法,调用方法需要有实例化对象,同时传入参数
		Name.invoke(object, "小明");    //相当于Person类对象.setName("小明")
		//取得setAge这个方法的实例化对象,设置方法名称与参数类型
		Method Age = class1.getMethod("setAge", int.class);
		//通过Method类对象调用指定的方法,调用方法需要有实例化对象,同时传入参数
		Age.invoke(object, 10);    //相当于Person类对象.setAge(10)
		System.out.println(object);
	}
}
4.反射调用类中的属性
注意:类中的所有属性一定在类对象实例化之后才会进行空间分配,所以此时如果想要调用类的属性,必须保证有实例化对象。
在Class类中提供有两组取得属性的方法:
(1)第一组(包括父类中)-取得类中全部属性:public Field[] getFields() throws SecurityException
(2)第一组(包括父类中)-取得类中指定名称属性:public Field getField(String name) throws NoSuchFieldException, SecurityException
(3)第二组(仅在本类中)-取得类中全部属性:public Field[] getDeclaredFields() throws SecurityException
(4)第二组(仅在本类中)-取得类中指定名称属性:public Method getDeclaredMethod(String name, Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException

如:取得类中全部属性

class Person{
	public String name;
	private int age;
}
class Students extends Person{
	private String school;
	public int num;
}
public class Test{
	public static void main(String[] args) {
		Class<?> class1 = Students.class;
		{//普通代码块
			//第一组-取得类中全部属性
			Field[] fields = class1.getFields();
			for (Field field : fields) {
				System.out.println(field);
			}
		}
		System.out.println("**********************************");
		{
			//第二组-取得类中全部属性
			Field[] fields = class1.getDeclaredFields();
			for (Field field : fields) {
				System.out.println(field);
			}
		}
	}
}
注意:第一组只能取得public的;第二组既能取得public的,也能取得private的。

还有几个重要方法:

        (1)设置属性内容:

public void set(Object obj, Object value) throws IllegalArgumentException,IllegalAccessException

        (2)取得属性内容:

public Object get(Object obj) throws IllegalArgumentException,IllegalAccessException

(3)动态设置封装:

public void setAccessible(boolean flag) throws SecurityException

(4)取得属性的类型:

public Class<?> getType()

如:

class Person{
	public String name;    //public 修饰
	private int age;    //private 修饰
}
public class Test{
	public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException, InstantiationException {
		Class<?> class1 = Person.class;
		Object object = class1.newInstance();
		{
			Field nameField = class1.getDeclaredField("name");
			nameField.set(object, "小明");    //相当于 对象.name = "小明"
			System.out.println(nameField.get(object));
		}
		System.out.println("************************************");
		{
			//因为是private修饰的,所以会报错
//			Field ageField = class1.getDeclaredField("age");
//			ageField.set(object, 10);
//			System.out.println(ageField.get(object));
			//动态设置封装
			Field ageField = class1.getDeclaredField("age");
			ageField.setAccessible(true);
			ageField.set(object, 10);
			System.out.println(ageField.get(object));
		}
		System.out.println("************************************");
		{
			//取得属性类型
			Field nameField = class1.getDeclaredField("name");
			Field ageField = class1.getDeclaredField("age");
			System.out.println(nameField.getType());
			System.out.println(ageField.getType());
		}
	}
}
反射继承结构

猜你喜欢

转载自blog.csdn.net/wzh_123_123/article/details/80329550
今日推荐