Java反射
来源:互联网 发布:c语言编程求最简分数 编辑:程序博客网 时间:2024/05/16 14:22
注:内如来自慕课网:
http://www.imooc.com/learn/199
一、反射的概念
1.在面向对象的世界里,万事万物皆对象。
java中:静态的成员、普通数据类型是不是对象呢?
其实:前者是属于某个类的、而后者有包装类来封装成对象;
那么我们自己写的类呢?
其实我们自己写的类本身也是对象,他属于java.lang.Class类的实例对象;
There is a class named Class
所以,在面向对象世界里,万事万物皆对象。
Class源代码
构造器私有化,仅可以JVM调用
/* * Private constructor. Only the Java Virtual Machine creates Class objects. * This constructor is not used and prevents the default constructor being * generated. */ private Class(ClassLoader loader) { // Initialize final field for classLoader. The initialization value of non-null // prevents future JIT optimizations from assuming this final field is null. classLoader = loader; }
2.如何表示他呢?
/** * Author:林万新 lwx * Date: 2017/11/14 * Time: 18:42 */public class ClassDemo1 { public static void main(String[] args) { //Foo的实例对象如何表示? Foo foo1 = new Foo(); //Foo这个类本身也是实例对象,属于Class类的对象 //任何一个类都是Class类的实例对象,表示方式3种 //1,知道类名创建。告诉我们任何一个类都有一个隐含的静态成员变量:class Class c1 = Foo.class; //2.已知该类的对象。通过getClass方法 Class c2 = foo1.getClass(); //c1,c2表示了Foo类的类 类型(class type),类比其他基本类型啊,什么的 //这个对象称为该类的类 类型 //c1 or c2都代表了Foo类的类类型,1个类只可能是Class类的一个实例对象 System.out.println(c1 == c2); //3. Class c3= null; try { c3 = Class.forName("Fanshe.Foo"); } catch (ClassNotFoundException e) { e.printStackTrace(); } System.out.println(c3 == c2); //通过类的类类型创建该类的实例 try { Foo foo = (Foo) c1.newInstance();//前提是需要无参的构造方法 foo.foo(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } }}class Foo{ public void foo(){ System.out.println("foo"); }}
运行结果:
动态加载
这里需要用记事本操作一下实现类编译、运行,就能明白什么道路了:
1.如果是用new 来创建对象,那么就属于静态加载,编译时期就要全部加载,其中某个类没创建就会报错;
2.但是如果用Class.for.name()来动态加载,用到哪个类就加载运行哪个,而不是全部一下子加载完毕才可以运行,
通过反射获取类对象的信息
/** * Author:林万新 lwx * Date: 2017/11/14 * Time: 19:40 */public class ClassDemo2 { public static void main(String[] args) { //基本类型都有类类型 Class c1 = int.class; Class c2 = String.class;//可以理解成String类字节码(.class) Class c3 = Double.class; Class c4 = double.class; Class c5 = void.class; System.out.println(c1.getName()); System.out.println(c2.getName()); System.out.println(c2.getSimpleName());//没有包名的名称 System.out.println(c5.getName()); }}运行结果:intjava.lang.StringStringvoid
Class类的基本API使用
/** * Author:林万新 lwx * Date: 2017/11/14 * Time: 19:58 */public class ClassUtil { /** * 打印类对象的方法 * * @param obj */ public static void printClassMethodMessage(Object obj){ //1.获取类的类类型 Class c = obj.getClass();//传递的是那个子类的对象,c就是该子类的类类型 //获取类的名称 System.out.println("类的名称:"+ c.getName()); /**Method类 * 一个成员方法就是1个Method对象 * getMethods()获取所有public函数,包括父类继承而来的 * getDeclaredMethods()获取该类自己声明的方法 * * 比如:int test(int ,int ) */ Method[] ms = c.getMethods(); for (int i = 0; i <ms.length ; i++) { //得到的是返回值类型的类类型 Class returnType = ms[i].getReturnType(); System.out.print(returnType.getName()+ " "); //方法名称 System.out.print(ms[i].getName() +"("); //获取参数类型 Class[] paramTypes = ms[i].getParameterTypes(); for(Class class1 : paramTypes) System.out.print(class1.getName()+","); System.out.println(")"); } } /** * 打印类对象的成员变量 * @param obj */ public static void printFieldMessage(Object obj){ Class c = obj.getClass(); /** * 成员变量也是对象: 比如:int name java.lang.reflect.Filed Field类封装了关于成员变量的操作 getFields()方法获取的是public的成员变量信息 getDeclaredFileds获取的是该类自己声明的成员变量信息 */ Field[] fs = c.getDeclaredFields(); for(Field field : fs){ Class fieldType = field.getType();//得到比如:int.class String typeName = fieldType.getName();//得到成员类型 ;int String fieldName = field.getName();//得到成员变量的名称:name System.out.println(typeName + " " + fieldName); } } /** * 打印类对象的构造信息 * @param obj */ public static void printConMessage(Object obj){ Class c = obj.getClass(); /** * Constructor构造函数也是对象 * java.lang.Constructor封装了构造函数的信息 */ //Constructor[] cs = c.getConstructors();这是获取public的构造函数 Constructor[] cs = c.getDeclaredConstructors();//得到所有的,也就是自己声明的 for(Constructor constructor : cs){ System.out.print(constructor.getName()+"("); //获取他的参数列表的类类型 Class [] paramTypes = constructor.getParameterTypes(); for(Class class1:paramTypes) System.out.print(class1.getName() + ","); System.out.println(")"); } }}
public class ClassDemo3 { public static void main(String[] args) { String s = "hello"; ClassUtil.printClassMethodMessage(s); ClassUtil.printFieldMessage(s); ClassUtil.printConMessage(s); }}
运行结果部分显示:
方法反射调用类对象方法执行
/** * Author:林万新 lwx * Date: 2017/11/14 * Time: 21:33 */public class MethodDemo1 { public static void main(String[] args) { //获取print(int,int)方法 //第1步.获取类的类类型 A a1 = new A(); Class c = a1.getClass(); //2.获取方法: 名称和参数列表 //c.getMethod()获取的是public方法 //c.getDeclaredMethod()获取自己声明的方法 try { // Method m = c.getMethod("print",new Class[]{int.class,int.class}); Method m = c.getMethod("print", int.class, int.class); // a1.print(10,20);以前的会这样子调用 //方法的反射操作:用m对象来进行方法的调用 //方法如果没有返回值返回null,如果有返回具体的返回值 try { //m.invoke(a1,new Object[]{10,20}); m.invoke(a1,10,20); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } catch (NoSuchMethodException e) { e.printStackTrace(); } System.out.println("==============="); try { //获取方法print(String,String) Method m1 = c.getMethod("print", String.class, String.class); try { //用方法反射操作 m1.invoke(a1,"hello","world"); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } catch (NoSuchMethodException e) { e.printStackTrace(); } System.out.println("============"); try { Method m2 = c.getMethod("print"); try { m2.invoke(a1); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } catch (NoSuchMethodException 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 a,String b){ System.out.println(a.toUpperCase()+"," + b.toLowerCase()); }}
运行结果
通过反射理解集合泛型的本质
/** * Author:林万新 lwx * Date: 2017/11/14 * Time: 22:21 */public class MethodDemo2 { public static void main(String[] args) { ArrayList list = new ArrayList(); ArrayList<String> list1 = new ArrayList<>(); list1.add("hello"); //list1.add(20);这个就不允许加入 Class c1 = list.getClass(); Class c2 = list1.getClass(); System.out.println(c1 == c2);//输出true,说明编译之后集合的泛型是去泛型化的 //反射的操作都是编译之后的操作,因为是.class字节码文件。编译完之后才进行的,也就是运行时操作 //集合的泛型是防止错误输入,只在编译阶段有效,绕过编译就无效了; //验证:用反射才验证, try { Method m = c2.getMethod("add",Object.class); try { m.invoke(list1,100); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } System.out.println(list1.size()); System.out.println(list1);//不允许for each遍历 } catch (NoSuchMethodException e) { e.printStackTrace(); } }}
运行结果:
阅读全文
0 0
- 【反射】JAVA反射机制
- JAVA 反射
- java 反射
- Java反射
- java反射
- java反射
- JAVA反射
- java 反射
- Java 反射
- java 反射
- Java反射
- java反射
- JAVA 反射
- java 反射
- Java反射
- java反射
- java 反射
- java 反射
- 初入IT行业,从小白开始
- Android 视图View的基本属性
- 显式锁(四)--- Lock的等待/通知机制Condition
- HTML5
- Vulkan规范:第八章 8.2 ~ 8.3
- Java反射
- 行程长度编码科普
- 文章标题
- [系统安全]使用OD编写连连看外挂
- day-11
- thinkphp5 静态资源文件引入
- 简图记录-linux文件系统基础
- Vulkan规范:第八章 8.3 ~ 8.10
- Jmeter使用笔记