程序运行的时,能够改变程序结构或变量类型。典型的语言: Python,ruby,javascript等 如javascript代码: function test(){ var s = "var a = 3, var b = 4; alert(a+b)"; eval(s); } C、C++、Java不是动态语言,可是Java有必定的动态性,咱们能够利用反射机制、字节码操做得到相似动态语言的特性。 Java的动态性让编程的时候更加灵活。
指的是能够运行时加载、探知、使用编译期间彻底未知的类。javascript
程序在运行状态中,能够加载一个只有名称的类,对于任意一个已加载的类,都可以知道它的方法 和属性,对于任意一个对象,都能调用它的任意一个方法和属性。java
加载完类以后,在堆内存(HotSpot虚拟机是在方法区),就会产生一个Class对象(一个类只用一个Class 对象),这个对象包含整个类的结构信息。咱们能够经过这个对象看到类的结构。这个对象就像一面镜子,经过这个镜子能够个看到 类的结构,因此咱们称之为“反射”。编程
jdk对Class的介绍:数组
Class类的实例表示正在运行的Java应用程序中的类和接口。枚举是一种类,注释是一种接口。每一个数组属于被映射为Class 对象的一个类,全部具备相同元素类型和维数的数组都共享该 Class 对象。基本的Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也表示为 Class 对象。 Class没有公共构造方法。Class对象是在加载类时由Java虚拟机以及经过调用类加载器中的defineClass方法自动构造的。ruby
总结:this
Class类的对象包含了某个被加载类的结构,一个被加载类的对应一个Class对象。spa
当一个类被加载,或当加载器的defineClass()被JVM掉用,JVM便自动产生一个Class对象。.net
Class类是反射的根源。code
public class ClassTest { public static void main(String[] args) throws ClassNotFoundException { // (1)forName()获取Class对象(最经常使用) Class clazz1 = Class.forName("reflection.Student"); System.out.println(clazz1.hashCode()); // (2).class获取Class对象 Class clazz2 = String.class; System.out.println(clazz2.hashCode()); // (3)getClass()获取Class对象 // 一个类只对应一个Class对象 Class clazz3 = "reflection.Student".getClass(); System.out.println(clazz3.hashCode()); //每一个数组属于被映射为Class对象的一个类,全部具备相同元素类型和维数的数组都共享该Class对象 int[] arr01 = new int[10]; int[][] arr02 = new int[30][3]; int[] arr03 = new int[30]; double[] arr04 = new double[10]; System.out.println(arr01.getClass().hashCode()); System.out.println(arr02.getClass().hashCode()); System.out.println(arr03.getClass().hashCode()); System.out.println(arr04.getClass().hashCode()); } }
public class Student { public String name; private int age; 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; } private void myPrivateMethod(){ } public Student(String name, int age) { this.name = name; this.age = age; } //默认构造器反射的时候不要省略 public Student() { } } public class ClassTest { public static void main(String[] args) throws Exception { // 得到类型 Class clazz = Class.forName("reflection.Student"); System.out.println(clazz.getName()); System.out.println(clazz.getSimpleName()); // 得到属性 // 获取所有方法 Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { System.out.println("所有的属性:" + field.getName()); } // 获取public修饰的方法 Field[] fields1 = clazz.getFields(); for (Field field : fields1) { System.out.println("私有的属性:" + field.getName()); } // 得到方法 // 得到所有方法 Method[] methods = clazz.getDeclaredMethods(); // 方法名字 + 无参数 Method m01 = clazz.getDeclaredMethod("getName", null); // 方法名 + 有参数 Method m02 = clazz.getDeclaredMethod("setName", String.class); for(Method m:methods){ System.out.println("方法:"+m); } // 得到构造器 Constructor[] constructors = clazz.getDeclaredConstructors(); Constructor c = clazz.getDeclaredConstructor(String.class, int.class); System.out.println("得到构造器:"+c); for(Constructor temp:constructors){ System.out.println("构造器:"+temp); } } } //反射生成对象、调用普通方法、修改属性 public class ClassTest3 { public static void main(String[] args) throws Exception { //默认构造器产生对象 Class<Student> clazz = (Class<Student>) Class.forName("reflection.Student"); System.out.println(clazz.newInstance()); //指定构造器产生对象 Constructor<Student> c = clazz.getDeclaredConstructor(String.class, int.class); Student student = c.newInstance("xiaoming", 12); System.out.println("指定构造器产生对象后获取姓名: " + student.getName()); //反射调用普通方法 Method m = clazz.getDeclaredMethod("setName", String.class); m.invoke(student, "XIAOHUA "); System.out.println("反射调用普通方法修改姓名后获取姓名: " + student.getName()); //修改该属性 Student student1 = clazz.newInstance(); Field field = clazz.getDeclaredField("name"); field.setAccessible(true); field.set(student1, "wjk"); System.out.println(student1.getName()); System.out.println(field.get(student1)); } }
setAccessible(boolean flag)对象
(1) 将此对象的 accessible 标志设置为指示的布尔值。值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查。值为 false 则指示反射的对象应该实施 Java 语言访问检查。
(2) 设置false效率提升。
//验证 public class ClassTest4 { public static void test1() { Student student = new Student(); long start = System.currentTimeMillis(); for (Long i = 1L; i < 1000000L; i++) { student.getName(); } long end = System.currentTimeMillis(); System.out.println(end - start); } public static void test2() throws Exception { Student student = new Student(); Class clazz = student.getClass(); Method method = clazz.getDeclaredMethod("getName", null); long start = System.currentTimeMillis(); for (Long i = 1L; i < 1000000L; i++) { method.invoke(student); } long end = System.currentTimeMillis(); System.out.println(end - start); } public static void test3() throws Exception { Student student = new Student(); Class clazz = student.getClass(); Method method = clazz.getDeclaredMethod("getName", null); method.setAccessible(true); long start = System.currentTimeMillis(); for (Long i = 1L; i < 1000000L; i++) { method.invoke(student); } long end = System.currentTimeMillis(); System.out.println(end - start); } public static void main(String[] args) throws Exception { test1(); test2(); test3(); } } //结果 37 72 48
public class ClassTest5 { public static void test1(List<String> strings, Map<String, Object> map) { System.out.println("test1"); } public static List<String> test2() { return null; } public static void main(String[] args) throws Exception { Class clazz = ClassTest5.class; Method m = clazz.getMethod("test1", List.class, Map.class); Type[] t = m.getGenericParameterTypes(); for (Type type : t) { System.out.println("#" + type); if (type instanceof ParameterizedType) { Type[] genericTypes = ((ParameterizedType) type).getActualTypeArguments(); for (Type genericType : genericTypes) { System.out.println("泛型类型:" + genericType); } } } Method m2 = ClassTest5.class.getMethod("test2", null); Type returnType = m2.getGenericReturnType(); if (returnType instanceof ParameterizedType) { Type[] genericTypes = ((ParameterizedType) returnType).getActualTypeArguments(); for (Type genericType : genericTypes) { System.out.println("返回值,泛型类型:" + genericType); } } } } //结果 #java.util.List<java.lang.String> 泛型类型:class java.lang.String #java.util.Map<java.lang.String, java.lang.Object> 泛型类型:class java.lang.String 泛型类型:class java.lang.Object 返回值,泛型类型:class java.lang.String
参考:http://my.oschina.net/u/2361475/blog/597726