java反射
反射是java一个非常强大的功能,在实际业务开发中基本不会用到,但是在框架和一些工具中确实用的很多。
反射的主要特点就是通过已知的一些信息来获取Class对象,通过Class对象来进一步获取类的基本信息。通过反射可以构造出非常灵活而健壮的代码。
话不多说,上代码。
public class Human { private String name; private int age; static{ System.out.println("human静态代码块加载..."); } 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 void eat(String name){ System.out.println(name+":要吃饭!"); } @Override public String toString() { return "Human [name=" + name + ", age=" + age + "]"; } }
public class Teacher extends Human implements Serializable{ private static final long serialVersionUID = 1L; private String name; private int age; public Teacher(){ } public Teacher(String name, int age) { super(); this.name = name; this.age = age; } static{ System.out.println("Teacher静态代码块加载..."); } 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 void teach(String name){ System.out.println(name+"老师在教学"); } @Override public void eat(String name){ System.out.println(name+"老师吃东西"); } private String doSth(String param ){ return "Teacher [name=" + this.name + ", age=" + age + "] "+param; } @Override public String toString() { return "Teacher [name=" + name + ", age=" + age + "]"; } }
public class Test1 { public static void main(String[] args) throws ClassNotFoundException { //三种获取Class对象的方法。 Class<?> clazz1 = Class.forName("testreflect.Teacher"); Class<Teacher> clazz2 = Teacher.class; Teacher teacher = new Teacher(); Class<? extends Teacher> clazz3 = teacher.getClass(); //通过反射将类的基本信息打印出来 StringBuilder sb = new StringBuilder(); sb.append("package "+clazz1.getPackage().getName()+";\n\n"); sb.append(Modifier.toString(clazz1.getModifiers())+" "); sb.append(clazz1.getSimpleName()+" "); sb.append("extends "+clazz1.getSuperclass().getSimpleName()+" "); if(clazz1.getInterfaces().length > 0 ){ sb.append("implements "); for(Class<?> c : clazz1.getInterfaces()){ sb.append(c.getSimpleName()+","); } sb.setCharAt(sb.length()-1, ' '); sb.append("{\n"); }else{ sb.append("{\n"); } for(Field field : clazz1.getDeclaredFields()){ sb.append(" "+Modifier.toString(field.getModifiers())+" "); sb.append(field.getType().getSimpleName()+" "); sb.append(field.getName()+";\n"); } for(Constructor<?> constructor : clazz1.getConstructors()){ sb.append(" "+Modifier.toString(constructor.getModifiers())+" "); sb.append(clazz1.getSimpleName()+" "); sb.append("("); if(constructor.getParameters().length > 0){ for(Parameter parameter : constructor.getParameters()){ sb.append(parameter.getType().getSimpleName()+" "); sb.append(parameter.getName()+","); } sb.setCharAt(sb.length()-1, ')'); }else{ sb.append(")"); } sb.append(" {}\n\n"); } for(Method method : clazz1.getDeclaredMethods()){ sb.append(" "+Modifier.toString(method.getModifiers())+" "); sb.append(method.getReturnType().getSimpleName()+" "); sb.append(method.getName()+" ("); if(method.getParameters().length > 0){ for(Parameter parameter : method.getParameters()){ sb.append(parameter.getType().getSimpleName()+" "); sb.append(parameter.getName()+","); } sb.setCharAt(sb.length()-1, ')'); }else{ sb.append(")"); } sb.append(" {}\n\n"); } sb.append("}"); System.out.println(sb); } }
结果:
human静态代码块加载...
Teacher静态代码块加载...
package testreflect;
public Teacher extends Human implements Serializable {
private static final long serialVersionUID;
private String name;
private int age;
public Teacher (String arg0,int arg1) {}
public Teacher () {}
public String toString () {}
public String getName () {}
public void setName (String arg0) {}
public int getAge () {}
public void teach (String arg0) {}
public void eat (String arg0) {}
private String doSth (String arg0) {}
public void setAge (int arg0) {}
}
public class Test2 { public static void main(String[] args) throws Exception { Class<?> clazz = Class.forName("testreflect.Teacher"); Constructor<?> constructor = clazz.getConstructor(); Teacher teacher = (Teacher) constructor.newInstance(); teacher.setName("kyle"); teacher.setAge(20); Method doSth = clazz.getDeclaredMethod("doSth", String.class); doSth.setAccessible(true); Object result = doSth.invoke(teacher, "just do it"); System.out.println(result); Field name = clazz.getDeclaredField("name"); name.setAccessible(true); name.set(teacher, "stan"); System.out.println(teacher); } }
结果:
human静态代码块加载...
Teacher静态代码块加载...
Teacher [name=kyle, age=20] just do it
Teacher [name=stan, age=20]
上面的代码展示了反射的一些基本功能,通过上述代码测试可知,Class.forName("testreflect.Teacher")和Teacher.class获取Class对象时是有区别的,前者在加载.class文件后会进行初始化,而后者却不会。