还在那里硬编码吗?试试反射 | 打开新世界的大门

这是我参与更文挑战的第27天,活动详情查看: 更文挑战java

记得以前写了一篇json转实体的文章web

记得以前写了一篇json转实体的文章,里面就用到了java反射的文章,可是当时只是了解到反射这个知识点,并无深刻的了解,寒假闲来无事觉顶深刻整理一下java 反射的知识,一下都是我的学习反射的总结,不到之处,还望大神指点!!!面试

反射顾名思义就是和java编译相反的过程,这里实现的效果就是经过类名来进行实例化类对象并对类进行操做。具体看下json

获取父类和全部的接口

  • 首先咱们的java类是能够继承和实现多个接口的,那么咱们如何经过java反射获取java类的父类和接口呢?markdown

  • 首先咱们在这里新建一个Annimal做为父类架构

public class Annimal {

	private String AnnimalName;
	
	public void eat(){
		System.out.println("Annimal is eatting");
	}
	public void run(){
		System.out.println("Annimal is running");
	}
}
复制代码
  • 而后再新建一个Behaviour接口
public interface Behaviour {

	public String haviour="test";
	
	public void sayHello();
	
	public void isAngury();
	
	public void love();
}
复制代码
  • 如今让咱们新建一个Dog类并让Dog类继承Annimal类并实现Behavour这个接口
public class Dog extends Annimal implements Behaviour

复制代码
  • Dog源码
public class Dog extends Annimal implements Behaviour{

	private String dogName;
	
	public void fuck(String name){
		System.out.println("fuck To : "+name);
	}
	@Override
	public void sayHello() {
		// TODO Auto-generated method stub
		System.out.println("Dog sayHello");
	}

	@Override
	public void isAngury() {
		// TODO Auto-generated method stub
		System.out.println("Dog isAngury");
	}

	@Override
	public void love() {
		// TODO Auto-generated method stub
		System.out.println("Dog love");
	}

}
复制代码
  • 测试框架

  • 下面咱们开始进行测试,首先咱们经过Class类来获取类的class对象ide

Class<?> target=Class.forName("tom.change.Reflect.获取父类和全部接口.Dog");


复制代码
  • 而后经过getSuperClass和getInterfaces这两个方法就能够获取到父类和全部的接口
//获取Dog类的父类
Class<?> parent=target.getSuperclass();
//获取该类继承的全部类
Class<?> intefaces[]=target.getInterfaces();
复制代码
  • 最后看程序运行的效果图

这里写图片描述

获取全部的属性(getDeclaredFields)

  • 在Java类中出了类与类中关系,每一个类还有具备特定的属性,那么咱们如何经过反射来获取Java类中的属性呢。下面我写了一个user类,其中的属性为

Dog类:svn

private String dogName;
复制代码
  • 那么下面咱们来试试到底能不能获取上面的几个属性。一样经过类路径获取class对象
Class<?> clazz=Class.forName("tom.change.Reflect.获取父类和全部接口.Dog");
复制代码
  • 而后经过class对象的getDeclaredFields方法获取本地类的属性,这个方法是没法获取继承父类和接口中的属性,若是非要获取你能够先经过该类获取到父类,而后在去获取父类的class 对象,在去获取父类中属性。
for (int i = 0; i < fields.length; i++) {
			//获取字段的修饰权限符
			System.out.println(Modifier.toString(fields[i].getModifiers())+"@@@"+fields[i].getName());
		}
复制代码
  • 这里说一下,获取后用Field 来接受,这个类getModifiers是获取该属性的属性的,私有仍是公共仍是保护的。函数

  • 这里获取字段后,经过Field的set方法就能够给属性设置,无论属性的对外状态。前提是开启权限

field.setAccessible(true);
field.set(object, "21131084");
复制代码
  • 这里的object是class的一个实例化对象

获取类中的全部的方法(getMethods)

  • 在上面咱们已经获取了类中全部的属性,那么下面咱们天然就是获取类中的全部的方法了。一样的步骤上面已经有了,这里不赘述了,只不过和上面的不一样的地方就是获取class对象后咱们调用getMethods方法。
public void tom.change.Reflect.获取父类和全部接口.Dog.fuck(java.lang.String)
public void tom.change.Reflect.获取父类和全部接口.Dog.sayHello()
public void tom.change.Reflect.获取父类和全部接口.Dog.love()
public void tom.change.Reflect.获取父类和全部接口.Dog.isAngury()
public void tom.change.Reflect.获取父类和全部接口.Annimal.run()
public void tom.change.Reflect.获取父类和全部接口.Annimal.eat()
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 final void java.lang.Object.wait() throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
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()
复制代码
  • 你们有没有疑问,为何有一些莫名的方法出现,有些方法甚至咱们的Dog和继承类中都没有出现过,这是怎么回事呢。首先getMethods获取类自己的方法这是确定的。继承的类咱们也是能够获取的,这就解释了为何咱们的获取方法中有Annimal类中的方法,。那么后面那些Object类的方法是哪里来的呢,你们还记得吗全部的类都是继承Object类的。

类中方法的调用(getMethod)

  • 在上面咱们获取了方法后,经过getMethod获取指定的方法,该方法返回的是Method对象,而后经过Method里的invoke方法调用指定的方法。在调用的时候须要传入class实力化对象,有参数的话咱们还须要传入参数。
public Object invoke(Object obj, Object... args)
复制代码
  • 源码显示,方法须要参数有多少这里就传入多少,这里是通用的。

  • 在经过getMethod获取Method的时候咱们须要传入方法参数的类型

```
public Object invoke(Object obj, Object... args)
```

```
public Method getMethod(String name, Class<?>... parameterTypes)
```
复制代码

获取全部构造函数(getConstructors)

  • Java类中最后应该还剩下构造函数了,既然是反射,咱们就要将类反射的干干晶晶的。得到class对象后咱们经过getConstructors获取构造函数,该方法返回的是Constructor集合。在Constructor类中getParameterTypes获取构造函数中的参数,有个这个咱们就能够本身进行类的构造了。

这里写图片描述

总结

  • 到这里咱们的反射已经彻底能够操做一个类了。有人会问这有啥意思呢,在咱们Javaweb中,哪些知名的框架源码里必须有反射,经过反射咱们可以实现注解这个功能。固然注解还有其余知识,之后知道在介绍。再好比说咱们将map与实体进行映射这里就须要反射区获取Java Bean中的属性并将map的值赋值。无论怎么样,反射是咱们Java的重要知识,学会它对本身之后的架构方面试有很大的帮助的。

源码下载

相关文章
相关标签/搜索