反射

反射指的是对象的反向处理操作,必须先导入一个包,而后才能产生类的实例化对象。

所谓的“反”指的是根据对象来取得对象的来源信息,

而这个“反”的操作核心的处理就在于Object类的一个方法:

取得class对象:public final native Class<?> getClass();  该方法返回的是一个Class类对象,这个Class描述的就是类。

在反射的世界里面,看重的不再是一个对象,而是对象身后的组成(类,构造,普通,成员等)

反的本质:通过对象取得了对象的来源


Class类对象的三种实例化模式。

Class类描述的整个类的概念,也是整个反射的操作源头,在使用Class类的时候需要关注的依然是这个类的对象,而这个类的对象的产生模式一共有三种:

1.任何类的实例化对象可以通过Object类中的getClass()方法取得实例化对象。public final native Class<?> getClass();

2.“类.class”:直接根据某个具体的类来取得Class类的实例化对象。

3.使用Class类提供的方法:public static Class<?> forName(String className)throws ClassNotFoundException

以上除了第一种会产生Date类的实例化对象之外,其他的两种都不会产生Date类的实例化对象。于是取得了Class类对象有一个最直接的好处:可以通过反射实例化对象。

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

public T newInstance() throws InstantiationException,IllegalAccessException


因为Class类可以使用newInstance()实例化对象,同时Class.forName()能够接收类名称


取得了Class对象就意味着取得了一个指定类的操作权



反射与类操作

利用反射可以做出一个对象所具备的所有操作行为,最为关键的是这一切的操作都基于Object进行。

取得父类信息

取得类的包名称:public Package getPackage{}

取得父类的Class对象:public native Class<? super T>getSuperclass();

取得实现的父接口:public Class<?>[] getInterfaces()

interface IFruit{}
interface IMessage{}
class CLS implements IFruit,IMessage{}
 public class Fanshe{
	 public static void main(String[] args) {
		Class<?> cls=CLS.class;
		System.out.println(cls.getPackage().getName());
		System.out.println(cls.getSuperclass().getName());
		Class<?>[] iClass=cls.getInterfaces();
		for(Class<?> class1:iClass) {
			System.out.println(class1.getName());
		}
	}
 }
结果
www.bit.java.testthread
java.lang.Object
www.bit.java.testthread.IFruit
www.bit.java.testthread.IMessage


反射调用构造

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

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

取得类中的所有构造:

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

以上两个方法返回的类型都是java.lang.reflect.Constructor类的实例化对象,这个类之中大家只需要关注一个方法

实例化对象:

public T newInstance(Object....initargs)

throws InstantiationException,IllegalAccessException,IllegalArgumentException,InvocationTargetException

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

结果:

public www.bit.java.testthread.Person()

public www.bit.java.testthread.Person(java.lang.String)

public www.bit.java.testthread.Person(java.lang.String,int)

以上的操作是直接利用了Constructor类中的toString()方法取得了构造方法的完整信息(包含方法权限,参数列表),而如果只使用getName()方法,只会返回构造方法的包名.类名



反射调用普通方法(核心)

取得全部普通方法:

public Method[] getMethod()  throws SecurityException

取得指定的普通方法:

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

以上两个方法的类型都是java.lang.reflect.Method类的对象,在此类中提供有一个调用方法的支持:

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

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 Fanshe{
	public static void main(String[] args)throws Exception{
		Class<?> cls=Person.class;
		Method[] methods=cls.getMethods();
		for(Method method:methods) {
			System.out.println(method);
		}
	}

}


结果:

public java.lang.String www.bit.java.testthread.Person.toString()

public java.lang.String www.bit.java.testthread.Person.getName()
public void www.bit.java.testthread.Person.setName(java.lang.String)
public int www.bit.java.testthread.Person.getAge()
public void www.bit.java.testthread.Person.setAge(int)
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()

之前程序编写的简单java类中的getter,setter方法采用的都是明确的对象调用。

而现在有了反射机制处理以后,即使没有明确Person类型对象(依然需要实例化对象,Object对象描述,所有的普通方法必须 在有实例化对象之后才能进行调用)。就可以通过反射调用

此方法的好处:不再局限于某一具体类型的对象,而是可以 通过Object类型进行所有类的方法的调用。


反射调用类中属性

前提:类中的所有属性一定在类对象实例化之后才能进行空间分配,所以此时如果想要调用类的属性,必须保证有实例化对象。通过反射的newInstance()可以直接取得实例化对象(Object类型)




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值