java反射的一些调试

时间:2021-07-12 03:30:05

额,研究过这个的人很多很多,但是我没有很深入的研究过,所以谁也拦不住我去研究研究,然后记录下来······如有雷同··那就雷同了···请多多包涵。


首先是整个项目的结构:

java反射的一些调试



使用到的类:

package reflect.demo;

public class Demo {

}

package reflect.person;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@AllArgsConstructor
@NoArgsConstructor
public @Data class Person {

	private String name;
	private int age;

	public Person(int age) {
		super();
		this.age = age;
	}

	public Person(String name) {
		super();
		this.name = name;
	}

}


package reflect.person1;

public interface China {
	public static final String name = "xxxxx";
	public static int age = 12;

	public void sayChina();

	public void sayHello(String name, int age);
}


package reflect.person1;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Person1 implements China {
	private String sex;

	@Override
	public void sayChina() {
		System.out.println("hello,china");
	}

	@Override
	public void sayHello(String name, int age) {
		System.out.println(name + "---" + age);
	}

}


package reflect;

import lombok.Getter;
import lombok.Setter;

public class HelloOriginal {
	@Getter
	@Setter
	private static Class<?> demo;

	static {
		try {
			demo = Class.forName("reflect.person1.Person1");
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}


1.凡是程序,都以HELLOWORLD来开始,貌似谁也避免不了哩。

package reflect.test1;

import reflect.demo.Demo;

/**
 * @author Administrator 通过一个对象获得完整的包名和类名
 */
public class Hello {
	public static void main(String[] args) {
		Demo demo = new Demo();
		System.out.println(demo.getClass().getName());
	}
}

这是反射的最最基础的东西了吧,我新建了一个对象,并且通过这个对象来获得它的class,有了class以后,我就可以操作class的相关信息了,这里我打印出了这个class的name属性。

这里就很容易的理解了反射,反射反射就是反过来搞。我们总是通过类来创建对象,而现在我们通过一个特定的对象(有时候我们不知道这个对象所属什么类)获得了它所归属的类的相关信息。

运行结果:

java反射的一些调试


2.创建class对象的三种方式

package reflect.test2;

import reflect.demo.Demo;

/**
 * @author Administrator 实例化Class类对象
 *
 */
public class Hello {
	public static void main(String[] args) {
		Class<?> demo1 = null;
		// Class<?>是一种泛型的表达,意思是Object类及其子类都可以放
		Class<?> demo2 = null;
		Class<?> demo3 = null;

		try {
			// 一般使用的方式,通过指定特定的名称来创建class
			demo1 = Class.forName("reflect.demo.Demo");
		} catch (Exception e) {
			e.printStackTrace();
		}

		demo2 = new Demo().getClass();//通过一个对象来获得class
		demo3 = Demo.class;//通过类来获得class

		System.out.println("类名称   " + demo1.getName());
		System.out.println("类名称   " + demo2.getName());
		System.out.println("类名称   " + demo3.getName());
	}

}

运行结果:

java反射的一些调试


3.通过反射来创建(实例化)一个对象,使用的是无参构造方法。

package reflect.test3;

import reflect.person.Person;

/**
 * @author Administrator 通过Class实例化其他类的对象
 * 
 *         通过无参构造实例化对象
 */
public class Hello {
	public static void main(String[] args) {
		Class<?> demo = null;
		try {
			demo = Class.forName("reflect.person.Person");//获得了特定名称的类的class对象
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		Person person = null;

		try {
			person = (Person) demo.newInstance();//使用class对象的newInstance()方法就可以创建一个对象了。
			/**
			 * 
			 * 
			 * */
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		person.setName("ri");
		person.setAge(1);

		System.out.println(person);
	}
}

4.通过有参的构造方法来构造对象

package reflect.test4;

import java.lang.reflect.Constructor;

import reflect.person.Person;

/**
 * @author Administrator
 *
 *         通过Class调用其他类中的构造函数 (也可以通过这种方式通过Class创建其他类的对象)
 */
public class Hello {

	public static void main(String[] args) {
		Class<?> demo = null;
		try {
			demo = Class.forName("reflect.person.Person");
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		Person per1 = null;
		Person per2 = null;
		Person per3 = null;
		Person per4 = null;

		Constructor<?> cons[] = demo.getConstructors();
		try {
			per4 = (Person) cons[0].newInstance();
			per3 = (Person) cons[1].newInstance("ri", 12);
			per1 = (Person) cons[2].newInstance("dd");
			per2 = (Person) cons[3].newInstance(12);
		} catch (Exception e) {
			e.printStackTrace();
		}

		System.out.println(per1);
		System.out.println(per2);
		System.out.println(per3);
		System.out.println(per4);

	}
}


5.通过反射来获得一个类所实现的接口

package reflect.test5;

/**
 * @author Administrator 返回一个类实现的接口
 */
public class Hello {
	public static void main(String[] args) {
		Class<?> demo = null;
		try {
			demo = Class.forName("reflect.person1.Person1");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}

		// 获得所有的接口
		Class<?> intes[] = demo.getInterfaces();
		for (int i = 0; i < intes.length; i++) {
			System.out.println("Person1实现的接口:" + intes[i].getName());
		}
	}
}

运行结果:

java反射的一些调试

6.通过反射来获得指定类的父类

package reflect.test6;


/**
 * @author Administrator 取得其他类中的父类
 */
public class Hello {
	public static void main(String[] args) {
		Class<?> demo = null;
		try {
			demo = Class.forName("reflect.person1.Person1");
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		Class<?> superClass = demo.getSuperclass();
		System.out.println("继承的父类为" + superClass.getName());
	}
}

运行结果:

java反射的一些调试


7.通过反射来获得指定类中的构造方法

package reflect.test7;

import java.lang.reflect.Constructor;

/**
 * @author Administrator获得其他类中的全部构造函数
 *
 */
public class Hello {

	public static void main(String[] args) {
		Class<?> demo = null;
		try {
			demo = Class.forName("reflect.person1.Person1");
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		Constructor<?> cons[] = demo.getConstructors();
		for (Constructor<?> con : cons) {
			System.out.println(con);
		}
	}
}

8.通过拼装的方式来获得构造方法(本质是获得构造方法的各种信息,我们也可以用在类的各种方法上)

package reflect.test8;

import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;

import reflect.HelloOriginal;

/**
 * @author Administrator 拼装获得构造方法的全部内容
 */
public class Hello extends HelloOriginal {
	public static void main(String[] args) {
		Constructor<?>[] cons = getDemo().getConstructors();
		for (Constructor<?> con : cons) {
			Class<?>[] pts = con.getParameterTypes();
			System.out.print("构造方法:  ");
			int mo = con.getModifiers();
			System.out.print(Modifier.toString(mo) + " ");
			System.out.print(con.getName());
			System.out.print("(");
			for (int i = 0; i < pts.length; i++) {
				System.out.print(pts[i].getName() + " arg" + i);
				if (i < pts.length - 1) {
					System.out.print(",");
				}
			}
			System.out.println("){}");
		}
	}
}


9.拼装类中的所有方法的签名

package reflect.test9;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

import reflect.HelloOriginal;

/**
 * @author Administrator拼接获得类中普通方法的所有内容(方法签名)
 *
 */
public class Hello9 extends HelloOriginal {
	public static void main(String[] args) {
		/*获得类中的所有方法*/
		Method[] methods = getDemo().getMethods();
		for (Method method : methods) {
			Class<?> returnType = method.getReturnType();/*获得方法的返回类型的class实例*/
			Class<?>[] pts = method.getParameterTypes();/*获得方法参数的class实例的数组*/
			int tem = method.getModifiers();/*获得方法的修饰符*/
			System.out.print(Modifier.toString(tem) + " ");
			System.out.print(returnType.getName() + " ");
			System.out.print(method.getName() + "(");
			for (int i = 0; i < pts.length; i++) {
				System.out.print(pts[i].getName() + "arg" + i);
				if (i < pts.length - 1) {
					System.out.print(",");
				}
			}

			Class<?>[] execs = method.getExceptionTypes();/*获得方法抛出的异常*/
			if (execs.length > 0) {
				System.out.print(") throws ");
				for (int j = 0; j < execs.length; j++) {
					System.out.print(execs[j].getName() + " ");
					if (j < execs.length - 1) {
						System.out.print(",");
					}
				}

			} else {
				System.out.print(")");
			}
			System.out.println("{}");
		}
	}
}

10.通过反射获得本类以及继承的属性

package reflect.test10;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

import reflect.HelloOriginal;

/**
 * @author Administrator取得其他类的全部属性吧
 *
 */
public class Hello extends HelloOriginal {

	public static void main(String[] args) {
		System.out.println("=================本类全部属性=====================");
		Field[] fields = getDemo().getDeclaredFields();
		for (int i = 0; i < fields.length; i++) {
			// 权限修饰符
			int mo = fields[i].getModifiers();
			String priv = Modifier.toString(mo);
			// 属性类型
			Class<?> type = fields[i].getType();
			System.out.println(priv + " " + type.getName() + " "
					+ fields[i].getName() + ";");
		}

		System.out
				.println("===============实现的接口或者父类的属性========================");
		Field[] fields1 = getDemo().getFields();
		for (Field filed : fields1) {
			// 权限修饰符
			int mo = filed.getModifiers();
			String priv = Modifier.toString(mo);
			// 属性类型
			Class<?> type = filed.getType();
			System.out.println(priv + " " + type.getName() + " "
					+ filed.getName() + ";");
		}
	}
}


11.通过反射来调用其他类中的方法

package reflect.test11;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import reflect.HelloOriginal;

/**
 * @author Administrator 通过反射调用其他类中的方法
 */
public class Hello extends HelloOriginal {
	public static void main(String[] args) {
		try {
			Method method = getDemo().getMethod("sayChina");
			method.invoke(getDemo().newInstance());

			method = getDemo().getMethod("sayHello", String.class, int.class);
			method.invoke(getDemo().newInstance(), "34324", 33);
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

12.通过反射调用其他类的get和set方法

package reflect.test12;

import java.lang.reflect.Method;

import reflect.HelloOriginal;

/**
 * @author Administrator 调用其他类的set和get方法
 */
public class Hello extends HelloOriginal {
	public static void main(String[] args) throws Exception {
		Object obj = getDemo().newInstance();
		setter(obj, "Sex", "男", String.class);
		getter(obj, "Sex");
	}

	public static void getter(Object obj, String att) throws Exception {
		Method method = obj.getClass().getMethod("get" + att);
		System.out.println(method.invoke(obj));
	}

	public static void setter(Object obj, String att, Object value,
			Class<?> type) throws Exception {
		Method method = obj.getClass().getMethod("set" + att, type);
		method.invoke(obj, value);

	}
}

13.通过反射操作其他类的属性

package reflect.test13;

import java.lang.reflect.Field;

import reflect.HelloOriginal;
import reflect.person1.Person1;

/**
 * @author Administrator 通过反射操作属性
 */
public class Hello extends HelloOriginal {
	public static void main(String[] args) throws Exception {
		Object obj = getDemo().newInstance();

		Field field = getDemo().getDeclaredField("sex");
		field.setAccessible(true);
		field.set(obj, "女");
		System.out.println(((Person1) obj).getSex());

	}
}
14.通过反射获取并修改数组的信息

package reflect.test14;

import java.lang.reflect.Array;

import reflect.HelloOriginal;

/**
 * @author Administrator 通过反射获取并修改数组的信息
 */
public class Hello extends HelloOriginal {
	public static void main(String[] args) {
		int[] tem = { 1, 2, 3, 4, 5 };
		Class<?> test = tem.getClass().getComponentType();
		System.out.println("数组类型" + test.getName());
		System.out.println("数组长度  " + Array.getLength(tem));
		System.out.println("数组的第一个元素: " + Array.get(tem, 0));
		Array.set(tem, 0, 100);
		System.out.println("修改之后数组第一个元素为: " + Array.get(tem, 0));
	}
}

15.通过反射修改数组的大小

package reflect.test15;

import java.lang.reflect.Array;

/**
 * @author Administrator 通过反射修改数组大小
 */
public class Hello {
	public static void main(String[] args) {
		int[] temp = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
		int[] newTmep = (int[]) arrayInc(temp, 15);
		print(newTmep);
		String[] atr = { "a", "b", "c" };
		String[] str1 = (String[]) arrayInc(atr, 8);
		print(str1);
	}

	public static Object arrayInc(Object obj, int len) {
		Class<?> tem = obj.getClass().getComponentType();
		Object newArr = Array.newInstance(tem, len);
		int co = Array.getLength(obj);
		System.arraycopy(obj, 0, newArr, 0, co);
		return newArr;
	}

	public static void print(Object obj) {
		Class<?> clazz = obj.getClass();
		if (!clazz.isArray()) {
			return;
		}
		System.out.println("数组长度为----" + Array.getLength(obj));
		for (int i = 0; i < Array.getLength(obj); i++) {
			System.out.println(Array.get(obj, i));
		}
	}
}

16.通过反射获得类加载器

package reflect.test16;

import reflect.person.Person;

/**
 * @author Administrator 获得类加载器
 */
public class Hello {
	public static void main(String[] args) {
		Person person = new Person();
		System.out.println(person.getClass().getClassLoader().getClass());
	}
}


17.使用java的代理

package reflect.subject;

public interface Subject {
	public String say(String name, int age);
}

package reflect.subject;

public class RealSubject implements Subject {

	@Override
	public String say(String name, int age) {
		return name + "  " + age;
	}

}


package reflect.subject;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class MyInvocationHandler implements InvocationHandler {
	private Object obj = null;

	public Object bind(Object obj) {
		this.obj = obj;
		return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj
				.getClass().getInterfaces(), this);
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		System.out.println(proxy.getClass());
		return method.invoke(this.obj, args);
	}

}


package reflect.test17;

import reflect.subject.MyInvocationHandler;
import reflect.subject.RealSubject;
import reflect.subject.Subject;

/**
 * @author Administrator 动态代理测试
 */
public class Hello {
	public static void main(String[] args) {
		MyInvocationHandler demo = new MyInvocationHandler();
		Subject sub = (Subject) demo.bind(new RealSubject());
		String info = sub.say("xxxxx", 20);
		System.out.println(info);
	}
}