Java反射
来源:互联网 发布:linux创建db2数据库 编辑:程序博客网 时间:2024/06/05 01:52
万事万物皆对象,类也是对象,类是java.lang.Class类的对象
当然 java中静态的成员,普通数据类型不是对象
获取类对象的三种方式:
package Refection1;public class Test1 { public static void main(String[] args) { //1Class c1=Person.class;//2Person p=new Person();Class c2=p.getClass();Class c3=null;try {//3c3=Class.forName("Refection1.Person");} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println((c1==c2)+","+(c2==c3));try {//获取类的实例 newInstance:必须要有无参构造方法Person p2=(Person)c3.newInstance();} catch (Exception e) {}} }class Person{}
动态加载类
①:new出来的对象属于静态加载,需要在编译期间就要加载所有可能用到的资源
(如果有100个功能的话,需要把100个功能需要的资源加载才能运行这段程序而且不能出错一个,而你却只用1个功能)
package Refection2;public class Excel { public void start(){ System.out.println("excel.start"); }}
package Refection2;public class Word { public void start(){ System.out.println("word.start"); }}
package Refection2;public class Office { public static void main(String[] args) { args=new String[1]; //args[0]="Word"; args[0]="Excel"; if("word".equals(args[0])){ //new 对象是静态加载的 编译时刻需要加载所有可能需要用到的资源 Word w=new Word(); w.start(); } if("Excel".equals(args[0])){ Excel e=new Excel(); e.start(); }}}
②:动态加载类:运行时期加载,需要什么资源加载什么资源
(100个功能的话,需要用到一个功能,也就只需要在运行期间加载该功能所需要的资源,其他功能如果出错也不影响自己的使用)
需要制定一个规范(接口)
package Refection2;public class Word implements OfficeAble{ public void start(){ System.out.println("word.start"); }}
package Refection2;public class Excel implements OfficeAble{ public void start(){ System.out.println("excel.start"); }}
package Refection2;public interface OfficeAble { public void start();}
package Refection2;public class OfficeBetter { public static void main(String[] args) { args=new String[1]; //args[0]="Refection2.Word"; args[0]="Refection2.Excel"; try{ //动态加载类 在运行时刻加载 Class c=Class.forName(args[0]); //创建该类的实例 OfficeAble oa=(OfficeAble) c.newInstance(); oa.start(); }catch(Exception ex){ }}}
获取对象的类信息:
package Refection3;public class Test {public static void main(String[] args) {// TODO Auto-generated method stubString s="hello world"; // ClassUtil.printClassMethodMessage(s); // ClassUtil.printFieldMessage(s); ClassUtil.printConMessage(s);}}
package Refection3;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.Method;public class ClassUtil {/** * 获取对象的方法信息 * 一个成员方法就是一个Method对象 * getMethods()方法获取的是所有的public的函数,包括父类继承而来的 * getDeclaredMethods()获取的是所有该类自己声明的方法,不问访问权限 * @param obj */public static void printClassMethodMessage(Object obj) {Class c = obj.getClass();System.out.println("Class Name: " + c.getName());Method[] ms = c.getMethods();//c.getDeclaredMethods()for (int i = 0; i < ms.length; i++) {//返回值类型Class returnType = ms[i].getReturnType();System.out.print("返回值类型:"+returnType.getName() + " ");System.out.print("方法名:"+ms[i].getName()+" ");//参数类型System.out.print("参数类型:");Class[] paramTypes = ms[i].getParameterTypes();for (Class class1 : paramTypes) {System.out.print(class1.getName());}System.out.println(")");}}/** * 获取成员变量的信息 */public static void printFieldMessage(Object obj){Class c=obj.getClass();/* * 成员变量也是对象 * java.lang.reflect.Field * Field类封装了关于成员变量的操作 * getFields()方法获取的是所有的public的成员变量的信息 * getDeclaredFields获取的是该类自己声明的成员变量的信息 *///Field[] fs = c.getFields();Field [] fs=c.getDeclaredFields();for(Field field : fs){//得到成员变量的类型的类类型Class fieldType=field.getType();String typeName=fieldType.getName();//得到成员变量的名称String fieldName=field.getName();System.out.println(typeName+" "+fieldName);}}/** * 打印构造函数的信息 */public static void printConMessage(Object obj){Class c=obj.getClass();/* * 构造函数也是对象 * java.lang. Constructor中封装了构造函数的信息 * getConstructors获取所有的public的构造函数 * getDeclaredConstructors得到所有的构造函数 *///Constructor[] cs = c.getConstructors();Constructor[] cs=c.getDeclaredConstructors();for(Constructor constructor:cs){ System.out.print("构造器名称:"+constructor.getName()); Class[] paramTypes=constructor.getParameterTypes(); System.out.print(" 参数列表:"); for(Class class1:paramTypes){ System.out.print(class1.getName()+","); } System.out.println(")");}}}
方法反射的基本操作
方法的名称和方法的参数列表才能唯一决定某个方法
package Refection4;import java.lang.reflect.Method;public class MethodDemo1 {public static void main(String[] args) { //要获取print(int ,int )方法 1.要获取一个方法就是获取类的信息,获取类的信息首先要获取类的类类型A a1 = new A();Class c = a1.getClass();/* * 2.获取方法 名称和参数列表来决定 * getMethod获取的是public的方法 * getDelcaredMethod自己声明的方法 */ 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对象来进行方法调用 和a1.print调用的效果完全相同 //方法如果没有返回值返回null,有返回值返回具体的返回值 //Object o = m.invoke(a1,new Object[]{10,20}); Object o = m.invoke(a1, 10,20); System.out.println("=================="); //获取方法print(String,String) Method m1 = c.getMethod("print",String.class,String.class); //用方法进行反射操作 //a1.print("hello", "WORLD"); o = m1.invoke(a1, "hello","WORLD"); System.out.println("==================="); // Method m2 = c.getMethod("print", new Class[]{}); Method m2 = c.getMethod("print"); // m2.invoke(a1, new Object[]{}); m2.invoke(a1);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();} }}class A{public void print(){System.out.println("helloworld");}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());}}
=============================================================================
package com.imooc.reflect;import java.io.BufferedReader;import java.io.InputStreamReader;import java.lang.reflect.Method;public class MethodDemo2 {public static void main(String[] args) {UserService us = new UserService();/* * 通过键盘输入命令执行操作 * 输入update命令就调用update方法 * 输入delete命令就调用delete方法 * ... */try {BufferedReader br = new BufferedReader(new InputStreamReader(System.in));System.out.println("请输入命令:");String action = br.readLine();/*if("update".equals(action)){us.update();}if("delete".equals(action)){us.delete();}if("find".equals(action)){us.find();}*//* * action就是方法名称, 都没有参数--->通过方法的反射操作就会简单很多 * 通过方法对象然后进行反射操作 */Class c = us.getClass();Method m = c.getMethod(action);m.invoke(us);} catch (Exception e) {e.printStackTrace();}}}
package com.imooc.reflect;public class UserService {public void delete(){System.out.println("删除用户");}public void update(){System.out.println("修改用户");}public void find(){System.out.println("查找用户");}}
package com.imooc.reflect;//标准的JavaBean类有私有属性都对应有get/set方法,有无参数的构造方法public class User {private String username;private String userpass;private int age;public User(){}public User(String username, String userpass, int age) {super();this.username = username;this.userpass = userpass;this.age = age;}//get和set方法
update
修改用户
==============================================================================
package Refection4;import java.lang.reflect.Method;import java.util.ArrayList;import java.util.List;public class MethodDemo4 {public static void main(String[] args) {// TODO Auto-generated method stubArrayList list =new ArrayList(); List<String> lists =new ArrayList<>(); lists.add("hello"); Class c1=list.getClass(); Class c2=lists.getClass(); System.out.println(c1==c2); //反射的操作都是编译之后的操作 /* * c1==c2结果返回true说明编译之后集合的泛型是去泛型化的 * Java中集合的泛型,是防止错误输入的,只在编译阶段有效, * 绕过编译就无效了 * 验证:我们可以通过方法的反射来操作,绕过编译 */ try{ Method m=c2.getMethod("add", Object.class); m.invoke(lists, 20); System.out.println(lists.size()); //这时就不能用加强for循环去遍历了 System.out.println(lists); }catch(Exception ex){ }}}
true
2
[hello, 20]
阅读全文
0 0
- 【反射】JAVA反射机制
- JAVA 反射
- java 反射
- Java反射
- java反射
- java反射
- JAVA反射
- java 反射
- Java 反射
- java 反射
- Java反射
- java反射
- JAVA 反射
- java 反射
- Java反射
- java反射
- java 反射
- java 反射
- 第七期 使用Qemu+Buildroot+Eclipse打造一个优雅的开发环境 《虚拟机就是开发板》
- Bzoj 4204: 取球游戏
- 获取元素的三种DOM方法
- 杭电 2049
- crond服务和crontab命令
- Java反射
- Golang教程:(四)类型
- LintCode python 小白1
- 以r+方式fopen文件,写不进去内容
- camera sensor的分类及区别
- springboot使用第三方的json解析框架fastjson
- html入门
- PyCharm使用技巧:Find in Path(全局查找)、Find(当前文件查找)
- 使用prettyTime实现几分钟前,几小时前,几天前