自己最近在学习中碰到有关反射的知识点,自己之前自学Java基础的时候还有印象,现在不怎么用,忘了一大部分,现在做个总结。
百度百科 这样介绍Java反射机制:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
Demo地址
常用的Java反射机制有如下几种方法:
1:通过一个对象获得完整的包名和类名
TestRefect testRefect = new TestRefect();//自己定义的一个类
System.out.println(testRefect.getClass().getName());//返回包名和类名
System.out.println(testRefect.getClass().getSimpleName());//只返回类名
2:实例化Class类对象
Class<?> class1 = null;
Class<?> class2 = null;
Class<?> class3 = null;
try {
//第一种方法最常用
class1 = Class.forName("zpf.TestRefect");
class2 = new TestRefect().getClass();
class3 = TestRefect.class;
System.out.println("class1>>>"+class1.getName());
System.out.println("class2>>>"+class2.getName());
System.out.println("class3>>>"+class3.getName());
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
3:获取一个对象的父类与实现的接口
try {
//先实例化对象
Class<?> clazz = Class.forName("zpf.TestRefect");
//实例化父类
Class<?> parentClass = clazz.getSuperclass();
System.out.println("获取父类的class>>>"+parentClass.getName());
//获取实现的接口
Class<?>[] interfaces = clazz.getInterfaces();
for(int i = 0;i < interfaces.length ;i++){
System.out.println(i+">>>"+interfaces[i].getName());
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
4: 通过反射机制实例化一个类的对象
try {
Class<?> class1 = Class.forName("zpf.User");
//1 实例化默认构造方法 set赋值
User user = (User)class1.newInstance();
user.setAge(22);
user.setName("zpf");
System.out.println(user);
//2 获取所有的构造函数
Constructor<?> cons[] = class1.getConstructors();
for (int i = 0; i < cons.length; i++) {
Class<?> clazz[] = cons[i].getParameterTypes();
System.out.println(i + ">>>");
for (int j = 0; j < clazz.length; j++) {
System.out.println(clazz[j].getName());
}
}
User user1= (User) cons[1].newInstance("zpf");
System.out.println("一个构造函数 >>>"+user1.toString());
User user0 = (User) cons[0].newInstance("zpf",22);
System.out.println("两个构造函数 >>>"+user0.toString());
User user2 = (User) cons[2].newInstance();
System.out.println("没有构造函数 >>>"+user2.toString());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
4:获取某个类的全部属性
try {
Class<?> class1 = Class.forName("zpf.User");
System.out.println("-----------本类的属性---------------");
//获取本类属性
Field[] fields = class1.getDeclaredFields();
for(int i = 0 ; i < fields.length ; i++){
//权限修饰符
int model = fields[i].getModifiers();
String string = Modifier.toString(model);
//属性类型
Class<?> type = fields[i].getType();
System.out.println(string+" "+ type.getName()+" " +fields[i].getName());
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("---------------父类或者接口的属性----------------------");
try {
Class<?> parent = Class.forName("zpf.User").getSuperclass();
//获取父类的属性
Field[] fields = parent.getFields();
for(int i = 0;i < fields.length; i++){
//权限修饰符
int model = fields[i].getModifiers();
String string = Modifier.toString(model);
//属性类型
Class<?> type = fields[i].getType();
System.out.println(string +" "+ type.getName()+" " + fields[i].getName());
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
5: 获取某个类中的全部方法
try {
Class<?> clazz = Class.forName("zpf.User");
Method method[] = clazz.getMethods();
for(int i = 0;i < method.length;i++){
Class<?> returnType = method[i].getReturnType();//获取返回类型
Class<?> para[] = method[i].getParameterTypes();//获取方法中的参数
String string = Modifier.toString(method[i].getModifiers());//获取权限修饰符
System.out.print(string);
System.out.print(returnType.getName());
System.out.println(method[i].getName());
for(int j = 0; j <para.length;j++){
System.out.println("para>>>>>>>>>>"+para[j].getName());
}
//抛出一些异常的方法
Class<?> exce[] = method[i].getExceptionTypes();
for(int c = 0; c < exce.length; c++){
System.out.println(exce[c].getName());
}
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
6:获取某个类中某个的方法
Class<?> clazz = Class.forName("zpf.User");
Method method = clazz.getMethod("printAge",int.class);
method.invoke(clazz.newInstance(),22);
7: 获取某个类中的成员变量
Class<?> clazz = Class.forName("zpf.User");
Object object = clazz.newInstance();
System.out.println(object);
//修改private修饰的值---
Field field = clazz.getDeclaredField("age");
field.setAccessible(true);
field.set(object,22);
System.out.println(field.get(object));
8:反射机制的动态代理
TestRefect testRefect = new TestRefect();
System.out.println("类加载器>>>"+testRefect.getClass().getClassLoader().getClass().getName());
MyInvocationHandler myInvocationHandler = new MyInvocationHandler();
Subject sub = (Subject) myInvocationHandler.bind(new RealSubject());
String info = sub.say(22, "zpf");
System.out.println(info);
9 : 通过反射获取数组的信息
int [] temp = {1,2,3,4};
Class<?> clazz = temp.getClass().getComponentType();
System.out.println("数组类型>>>"+clazz.getName());
System.out.println("数组长度>>>"+Array.getLength(temp));
System.out.println("数组的第一个元素>>>"+Array.get(temp,0));
Array.set(temp, 0, 15);
System.out.println("修改后的第一个元素>>>"+Array.getInt(temp, 0));
10:通过反射取得并修改数组的大小
int [] arrays = {1,2,3,4,5};
System.out.println("没有改变数组长度的值");
printValue(arrays);
System.out.println("改变数组长度的值");
int [] newArrays = (int[]) copyArray(arrays, 10);
printValue(newArrays);
String [] strings = {"z","p","f"};
System.out.println("没有改变数组长度的值");
printValue(strings);
System.out.println("改变数组长度的值");
String [] newStrings = (String[])copyArray(strings, 6);
printValue(newStrings);
//-------------------------------------------------------------
// 改变数字长度,并copy之前的值
public static Object copyArray(Object object, int newLength) {
Class<?> clazz = object.getClass().getComponentType();
Object newArray = Array.newInstance(clazz, newLength);
int oldCount = Array.getLength(object);
System.arraycopy(object, 0, newArray, 0, oldCount);
return newArray;
}
//打印
public static void printValue(Object object) {
Class<?> clazz = object.getClass();
if (!clazz.isArray()) {
return;
}
System.out.println("该数组的长度为>>>" + Array.getLength(object));
for (int i = 0; i < Array.getLength(object); i++) {
System.out.println("打印出新的数组的数值>>>" + Array.get(object, i) + " ");
}
11 : 工厂模式
fruit fruit = Factory.getInstance("zpf.Apple");
if (fruit != null) {
fruit.eat();
}