CLASS类
1) 在面向对象的世界里,万事万物皆对象.
在java中有两样东西不是面向对象 1.普通的数据类型(java中有封装类来弥补它) 2. java中静态的东西
2) 类是对象吗? 类是对象,类是java.lang.Class类的实例对象
3) 任何一个类都是CLass类的实例对象,有三种表示方法
第一种表示方法 Class c1 = (类名).class;
实际在告诉我们任何一个类都有一个隐含的静态成员变量class
第二种表示方法 已经知道该类的对象通过getClass方法
第三种官网 c1表示是类的类型(Classtype)万事万物皆对象 类也是对象 是Class类的实例队象这个对象我们称为该类的类类型
Class c3 = null;
c3 = Class.forName("reflexdemo.Foot") Class.forname中是类的全路径(含包名);
我们可以通过类的类类型创建该类 的对象实例 通过c1 或者c3创建
Foot foot=(Foot)c1.newInstance(); 需要强制类型转换
1 package reflexdemo; 2 3 /** 4 * @2018年4月6日 5 * @王 鸿 6 * @Administrator 7 */ 8 public class Foot { 9 public int age = 10; 10 } 11 12 测试类 13 14 package reflexdemo; 15 16 /** 17 * @2018年4月6日 18 * @王 鸿 19 * @Administrator 20 */ 21 public class Refle_Demo_01 { 22 public static void main(String[] args) throws Exception { 23 // 创建一个Foot的实例对象 24 Foot foot = new Foot(); 25 // 第一种 Foot这个类也是一个实例对象,Class类的对象 26 Class c1 = Foot.class; 27 // 第二种通过对象.getclass方法 28 Class c2 = foot.getClass(); 29 // 不管 c1 ,c2 都代表着Foot类的类型,一个类只可能是class类的一个实例对象 30 System.out.println(c1 == c2); 31 // 第三种表达方式 32 Class c3 = null; 33 // Class.forname中是类的全路径(含包名) 34 c3 = Class.forName("reflexdemo.Foot"); 35 System.out.println(c2 == c3); 36 // 创建类的实例 37 Foot foot1 = (Foot) c3.newInstance();// 需要无参的构造 38 System.out.println(foot1.age); 39 } 40 }
为什么需要反射?
1 通过new创建对象 是静态加载类,在编译时刻就需要加载所有的可能使用的类 (通过动态加载类可以解决该问题)
2 动态加载类是在运行的时刻加载 ------------------(一般情况下功能性的类使用动态加载类)
动态编译:运行时确定类型,绑定对象。动态编译最大限度发挥了java的灵活性,体现了多 态的应用,有以降低类之间的藕合性("套用别的博客一句话")
下面的代码可以看到通过类 来反射类的信息 包括构造 还有方法
package datatype; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; /** * @2018年4月7日 * @王 鸿 * @Administrator */ public class ClassMessage { /* * 打印类的信息 包括类的成员函数成员变量 */ public static void print(Object obj) { // 要获取类的信息 首先获取类的类类型 Class c = obj.getClass(); // 传递的是那个子类的对象 c 就是那个类的类类型 // 获取类的名称 System.out.println("类的名称:" + c.getClass()); /* * 一个成员方法就是一个 Method对象 .getMethods()是获取所有的public的函数包括父类继承而来 * * getDeclaredMethods()获取的是所有该类自己声明方法 */ Method[] methods = c.getMethods(); for (int i = 0; i < methods.length; i++) { // 的到方法的返回类型 Class returnType = methods[i].getReturnType(); System.out.print(returnType.getName()); // 得到方法的名称 System.out.print(methods[i].getName() + "("); // 获取参数的类型-->得到的是参数列表的类类型 Class[] parameterTypes = methods[i].getParameterTypes(); for (Class class1 : parameterTypes) { System.out.print(class1.getName()); } System.out.println(")"); FiledMessage(c); } } /* * 获取成员变量的信息 */ public static void FiledMessage(Object obj) { Class c = obj.getClass(); Field[] declaredFields = c.getDeclaredFields(); for (Field field : declaredFields) { // 得到成员变量的类型的类类行 Class filedtype = field.getType(); String name = filedtype.getName(); // 得到成员变量的名称 String filename = field.getName(); System.out.println(name + " " + filename); } } /* * 打印构造函数的信息 获得所有的构造方法 */ public static void Constructor(Object obj) { Class c = obj.getClass(); Constructor[] constructors = c.getDeclaredConstructors(); for (Constructor cs : constructors) { System.out.print(cs.getName() + "("); // 获取构造函数的参数列表 Class[] parameterTypes = cs.getParameterTypes(); for (Class class1 : parameterTypes) { System.out.print(class1.getName() + ","); } System.out.println(")"); } } } /* *打印方法 * 打印的方法是又新开了一个类 */ package datatype; import java.lang.reflect.Method; /** * @2018年4月8日 * @王 鸿 * @Administrator */ public class MethodMessage { public static void main(String[] args) throws Exception { A a = new A(); // 要想获得一个方法的信息首先要获得类的类类型 Class type = a.getClass(); // 获取方法 方法必须要有名称和参数列表 /* * getMethod 获取的是public的方法 getDeclaredMethod自己声明的方法 */ Method method = type.getDeclaredMethod("append", String.class, String.class); // 如果是私有的需要用.setAccessible(true) method.setAccessible(true); // 方法没有返回值返回的null 有返回值放回指定的返回值 method.invoke(a, "1", "2"); } } class A { public void print(int a, int b) { System.out.println(a + b); } private void append(String one, String two) { System.out.println(one + two); } } 测试类 package datatype; /** * @2018年4月7日 * @王 鸿 * @Administrator */ public class ClassMessageText { public static void main(String[] args) { Integer type = 2; String string = "s"; // ClassMessage.print(type); // ClassMessage.FiledMessage(new Integer(1)); ClassMessage.Constructor(string); } }
此处指截取了一张构造反射出来的结果
注意: 方法的反射 如果你的方法是私有的 需要加上 方法对象.setAccessible(true)
通过反射了解集合泛型的本质
反射的操作都是编译之后的操作,集合的泛型是去泛型化的
java 中的集合泛型 是防止 错误输入的,只在编译阶段有效 绕过编译就无效了
package genericparadigm; import java.lang.reflect.Method; import java.util.ArrayList; /** * @2018年4月8日 * @王 鸿 * @Administrator */ public class GenericList { public static void main(String[] args) throws Exception, SecurityException { // 非泛型集合 ArrayList one = new ArrayList(); // 泛型集合 ArrayList<String> list = new ArrayList<String>(); Class class1 = one.getClass(); Class class2 = list.getClass(); System.out.println(class1 == class2); // true Method method = class2.getMethod("add", Object.class); method.invoke(list, 1); System.out.println(list.size()); // 1 } }