12 | 在面向对象的世界中,万事万物皆对象。Java语言中,静态的成员,类是对象,类是Java.lang.class的实例对象 |
---|
三种表示方式
12345678910111213 | //1.实例在告诉我们任何一个类都有一个隐含的静态成员变量classClass c1 = new Foo(); //2.已知该类的对象通过getClass方法Class c2 = Foo.getClass(); //官方 c1,c2表示了Foo类的类类型(Class Type) //万事万物皆对象,类也是对象,是Class的对象 这个对象我们称为类类型 // 个人理解类类型意思是 类的类型 //c1 or c2 都是Foo的类类型 但一个类只可能是Class类的一个实例对象System.out.print(c1==c2) //3.通过类名字实例化Class c3 = Class.forName("com.xc.Foo");//填全称 会有异常 //通常可以通过类类型创建该类的实例对象Foo f1 = (Foo)c1.newInstance //需要做强制类型转换 需要有无参构造方法 会有异常 |
---|
通过Class.forName(“类的全称”) 类的加载方式(2种) 1、静态加载类 编译时,加载的类是静态加载类。 Foo foo = new Foo(); 创建对象是静态加载类,编译时就要加载所有要用到的类,如果其中 1 个类有问题,就无法通过编译。解决该问题,可以使用动态加载类。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19class office { pubic static void main(String[] args){ if("wrod".equals(args[0])){ Word word = new Word(); word.start(); } if("Excel".equals(args[0])){ Excel excel = new Excel(); excel.start(); } } } class word { public void start(){ System.out.print("word..start.."); } }
运行时,加载的类是动态加载类 Class.forName(“com.reflect.Foo”); 编译时不检查用到的类是否存在,运行时再检查。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23class officeBetter { pubic static void main(String[] args){ try{ //动态加载 Class c = Class.forNname(args[0]); office o = (office)c.newInstance(); }catch(Expction e){ e.printStackTrace(); } } } interface office { void start(); } class word implements office { public void start(){ System.out.print("word..start.."); } }
基本数据类型,void关键字都存在类类型 1 2 3 4 5class.getMethods()方法获取是该类的所有public方法,包括从父类继承的方法; class.getDeclareMethods()方法获取该类自行声明的所有方法,不论访问权限; method.getName()获取方法名 method.getReturnType()获取方法的返回值 method.getParameterTypes(),获取方法的参数类型的类类型数组class[]
基本的数据类型,void关键字等都存在类类型
Class c = 基类.class (int,String,double,void等)
Class类的基本API操作的 1 2 3 4 5 6c.getName()可以获取类的名称 c.getSimpleName();//不包含包名的类的名称 c.getMethods()获取类的【public方法】集合,【包括继承来的】 ***** 注意【所有方法都是Method类的对象】 c.getDeclaredMethods()获取的是所有该类【自己声明】的方法,【不问访问权限】
123456789101112 | 1. getReturnType()得到该方法的返回值类型的类类型(class),如int.class String.class2. getName()得到方法的名称3. getParameterTypes()获得参数列表类型的类类型,如参数为(int,int)则得到Class c1 = int.class; int的类类型Class c2 = String.class; String类的类类型 String类字节码Class c3 = double.class; double这个数据类类型的字节码表示方式Class c4 = Double.class; Double这个类的类类型字节码表示方式Class c5 = void.class; 表达了void这个类的类类型getName为这个类的类类型的具体名称 c1.getName ---> intc2.getName ---> java.lang.String 类的全称c2.getSimpleName ---> String 不包含包名的类的名称 |
---|
1234567891011121314151617181920212223242526272829 | public void printClassMessage(String obj){ //获取类的类类型 Class c = obj.getClass(); //获取类的名称 String className = c.getName(); System.out.println("obj = [" + className + "]"); //获取类的方法 /** * Method类,是方法对象 * 一个成员方法就是一个Method对象 * getMethods()方法获取的是所有public的函数, * 包括从父类继承而来的 *getDeclaredMethods()方法是获取该类所有自己声明的方法,不论访问权限 */ Method[] methods1 = c.getMethods(); for (int i = 0; i <methods1.length ; i++) { //得到方法返回值类型 Class returnType = methods1[i].getReturnType(); System.out.println("返回值 = [" + returnType.getName() + "]"); //得到方法名称 System.out.println("方法名 = [" + methods1[i].getName() + "]"); //获取参数类型 Class[] paramType = methods1[i].getParameterTypes(); for (Class class1:paramType) { System.out.println("参数类型 = [" + class1.getName() + "]"); } } } |
---|
12345678910111213 | public void printConstructor(String obj){ Class c = obj.getClass(); Constructor[] cs = c.getDeclaredConstructors(); for (int i = 0; i <cs.length ; i++) { System.out.print(cs[i].getName()+" ("); Class[] classes = cs[i].getParameterTypes(); for (Class classtype:classes) { System.out.print(classtype.getName()+","); } System.out.println(")"); }} |
---|
1234567891011121314151617181920212223242526272829303132333435 | public static void main(String[] args) { A a1 = new A(); //获取a1的类类型 Class c = a1.getClass(); //获取类类型的方法 try { //method 是获取名为print 参数为int,int的方法 //getMethod获取的是public的方法 //getDelcaredMethod自己声明的方法 //Method m = c.getMethod("print",new Class[]{int.class,int.class}); //Method m = c.getMethod("print",int.class,int.class); Method m = c.getMethod("print",String.class,String.class); //object 是方法的返回值没有返回值为null //m.invoke(a1,new Object[]{10,20}); Object o = m.invoke(a1,"hello","world"); // 当没有参数列表时 //Method m2 = c.getMethod("print"); Method m2 = c.getMethod("print",new Class[]{}); m2.invoke(a1); } catch (Exception e) { e.printStackTrace(); } }}class A{ public void print(){ System.out.println("空"); } public void print(int a,int b){ System.out.println(a+b); } public void print(String s1,String s2){ System.out.println(s1+s2); } |
---|
12345678910111213141516171819202122232425262728 | public static void main(String[] args) { ArrayList list = new ArrayList(); ArrayList<String> list1 = new ArrayList<String>(); list1.add("hello"); //list1.add(20);错误的 Class c1 = list.getClass(); Class c2 = list1.getClass(); System.out.println(c1 == c2); //反射的操作都是编译之后的操作 /* * c1==c2结果返回true说明编译之后集合的泛型是去泛型化的 * Java中集合的泛型,是防止错误输入的,只在编译阶段有效, * 绕过编译就无效了 * 验证:我们可以通过方法的反射来操作,绕过编译 */ try { Method m = c2.getMethod("add", Object.class); m.invoke(list1, 20);//绕过编译操作就绕过了泛型 System.out.println(list1.size()); System.out.println(list1); /*for (String string : list1) { System.out.println(string); }*///现在不能这样遍历 } catch (Exception e) { e.printStackTrace(); } } |
---|