Java反射机制实例代码分享
本文旨在对Java反射机制有一个全面的介绍,希望通过本文,大家会对Java反射的相关内容有一个全面的了解。 阅读本文之前,大家可先行参阅《重新理解Java泛型》。 前言 Java反射机制是一个非常强大的功能,在很多大型项目比如Spring,Mybatis都可以看见反射的身影。通过反射机制我们可以在运行期间获取对象的类型信息,利用这一特性我们可以实现工厂模式和代理模式等设计模式,同时也可以解决Java泛型擦除等令人苦恼的问题。本文我们就从实际应用的角度出发,来应用一下Java的反射机制。 反射基础 p.s: 本文需要读者对反射机制的API有一定程度的了解,如果之前没有接触过的话,建议先看一下官方文档的Quick Start。 在应用反射机制之前,首先我们先来看一下如何获取一个对象对应的反射类 通过getClass方法 在Java中,每一个 String s = "ziwenxie"; Class<?> c = s.getClass(); 我们也可以调用 Class<?> c = Class.forName("java.lang.String"); 使用.class或者我们也可以直接使用 Class<?> c = String.class; 获取类型信息在文章开头我们就提到反射的一大好处就是可以允许我们在运行期间获取对象的类型信息,下面我们通过一个例子来具体看一下。 首先我们在 package typeinfo.interfacea; public interface A { void f(); } 接着我们在 package typeinfo.packageaccess; import typeinfo.interfacea.A; class C implements A { public void f() { System.out.println("public C.f()"); } public void g() { System.out.println("public C.g()"); } protected void v () { System.out.println("protected C.v()"); } void u() { System.out.println("package C.u()"); } private void w() { System.out.println("private C.w()"); } } public class HiddenC { public static A makeA() { return new C(); } } 在 package typeinfo; import typeinfo.interfacea.A; import typeinfo.packageaccess.HiddenC; import java.lang.reflect.Method; public class HiddenImplementation { public static void main(String[] args) throws Exception { A a = HiddenC.makeA(); a.f(); System.out.println(a.getClass().getName()); // Oops! Reflection still allows us to call g(): callHiddenMethod(a,"g"); // And even methods that are less accessible! callHiddenMethod(a,"u"); callHiddenMethod(a,"v"); callHiddenMethod(a,"w"); } static void callHiddenMethod(Object a,String methodName) throws Exception { Method g = a.getClass().getDeclaredMethod(methodName); g.setAccessible(true); g.invoke(a); } } 从输出结果我们可以看出来,不管是 public C.f() typeinfo.packageaccess.C public C.g() package C.u() protected C.v() private C.w() 应用实践我们有下面这样一个业务场景,我们有一个泛型集合类 为了实现我们上面的例子,我们先来定义几个类: public class Pet extends Individual { public Pet(String name) { super(name); } public Pet() { super(); } } public class Cat extends Pet { public Cat(String name) { super(name); } public Cat() { super(); } } public class Dog extends Pet { public Dog(String name) { super(name); } public Dog() { super(); } } public class EgyptianMau extends Cat { public EgyptianMau(String name) { super(name); } public EgyptianMau() { super(); } } public class Mutt extends Dog { public Mutt(String name) { super(name); } public Mutt() { super(); } } 上面的 public class Individual implements Comparable<Individual> { private static long counter = 0; private final long id = counter++; private String name; // name is optional public Individual(String name) { this.name = name; } public Individual() {} public String toString() { return getClass().getSimpleName() + (name == null ? "" : " " + name); } public long id() { return id; } public boolean equals(Object o) { return o instanceof Individual && id == ((Individual)o).id; } public int hashCode() { int result = 17; if (name != null) { result = 37 * result + name.hashCode(); } result = 37 * result + (int) id; return result; } public int compareTo(Individual arg) { // Compare by class name first: String first = getClass().getSimpleName(); String argFirst = arg.getClass().getSimpleName(); int firstCompare = first.compareTo(argFirst); if (firstCompare != 0) { return firstCompare; } if (name != null && arg.name != null) { int secendCompare = name.compareTo(arg.name); if (secendCompare != 0) { return secendCompare; } } return (arg.id < id ? -1 : (arg.id == id ? 0 : 1)); } } 下面创建了一个抽象类 public abstract class PetCreator { private Random rand = new Random(47); // The List of the different getTypes of Pet to create: public abstract List<Class<? extends Pet>> getTypes(); public Pet randomPet() { // Create one random Pet int n = rand.nextInt(getTypes().size()); try { return getTypes().get(n).newInstance(); } catch (InstantiationException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } } public Pet[] createArray(int size) { Pet[] result = new Pet[size]; for (int i = 0; i < size; i++) { result[i] = randomPet(); } return result; } public ArrayList<Pet> arrayList(int size) { ArrayList<Pet> result = new ArrayList<Pet>(); Collections.addAll(result,createArray(size)); return result; } } 接下来我们来实现上面这一个抽象类,解释一下下面的代码,在下面的代码中,我们声明了两个集合类, public class LiteralPetCreator extends PetCreator { @SuppressWarnings("unchecked") public static final List<Class<? extends Pet>> allTypes = Collections.unmodifiableList( Arrays.asList(Pet.class,Dog.class,Cat.class,Mutt.class,EgyptianMau.class)); private static final List<Class<? extends Pet>> types = allTypes.subList( allTypes.indexOf(Mutt.class),allTypes.size()); public List<Class<? extends Pet>> getTypes() { return types; } } 总体的逻辑已经完成了,最后我们实现用来统计集合中相关 public class TypeCounter extends HashMap<Class<?>,Integer> { private Class<?> baseType; public TypeCounter(Class<?> baseType) { this.baseType = baseType; } public void count(Object obj) { Class<?> type = obj.getClass(); if (!baseType.isAssignableFrom(type)) { throw new RuntimeException( obj + " incorrect type " + type + ",should be type or subtype of " + baseType); } countClass(type); } private void countClass(Class<?> type) { Integer quantity = get(type); put(type,quantity == null ? 1 : quantity + 1); Class<?> superClass = type.getSuperclass(); if (superClass != null && baseType.isAssignableFrom(superClass)) { countClass(superClass); } } @Override public String toString() { StringBuilder result = new StringBuilder("{"); for (Map.Entry<Class<?>,Integer> pair : entrySet()) { result.append(pair.getKey().getSimpleName()); result.append("="); result.append(pair.getValue()); result.append(","); } result.delete(result.length() - 2,result.length()); result.append("} "); return result.toString(); } } 总结 以上就是本文关于Java反射机制实例代码分享的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站: Java编程打印购物小票实现代码 Java中的引用和动态代理的实现详解 Java编程实现月食简单代码分享 如有不足之处,欢迎留言指出。感谢朋友们对本站的支持! (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |