博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java反射 一些理解
阅读量:5975 次
发布时间:2019-06-20

本文共 6937 字,大约阅读时间需要 23 分钟。

JAVA反射机制

什么是反射:

  JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;
  对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
 
    
条件:
 
  JAVA反射(放射)机制:“程序运行时,允许改变程序结构或变量类型,这种语言称为 ”。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言。但是JAVA有着一个非常突出的动态相关机制:Reflection,
用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、
或唤起其methods。(百度百科)
  尽管java不是动态语言 但是java提供了一个非常重要的API用于完成反射的需求。Reflection
  
学习:
  要学习反射,先来介绍下需要学习或者理解的类(直接抄的API的解释词语) 其实能熟练读懂api比看一些教程有用的多
 
  1、
java.lang.Class<T>//Class 类的实例表示正在运行的 Java 应用程序中的类和接口。
 
  2、
java.lang.reflect(包)
  java.lang.reflect.Constructor<T> //提供关于类的单个构造方法的信息以及对它的访问权限。
  java.lang.reflect.Field //Field 提供有关类或接口的单个字段的信息,以及对它的动态访问权限。反射的字段可能是一个类(静态)字段或实例字段。
  java.lang.reflect.Method //Method 提供关于类或接口上单独某个方法(以及如何访问该方法)的信息。所反映的方法可能是类方法或实例方法(包括抽象方法)。
  java.lang.reflect.Modifier  //Modifier 类提供了 static 方法和常量,对类和成员访问修饰符进行解码。
 
  例子:
  
获取包名,类名.......
    
public static void main(String[] args) {        String strObj= new String();//创建对象,这种方式创建,比较容易理解创建了一个String对象        Class classObj = strObj.getClass();//获取了一个运行中的实例模型  有兴趣的可以去读一下源码,就不往外贴了        System.out.println(classObj.getName());//完整类名      System.out.println(classObj.getPackage().getName());//包名
//Result java.lang.String  java.lang  }

  实例化Class对象的方式:通常理解实例化一个类的Class模型,比如我使用的String这个类,就是实例化了一个String的Class的模型对象

public static void main(String[] args) throws Exception {        Class
classObj = null; classObj = Class.forName("java.lang.String");//返回与带有给定字符串名的类或接口相关联的 Class 对象。(API) System.out.println(classObj.getName()); classObj=new String().getClass(); System.out.println(classObj.getName()); classObj=String.class; System.out.println(classObj.getName()); //Result java.lang.String java.lang.String java.lang.String }
  获取父类和接口
public static void main(String[] args) throws Exception {        Class
classObj = null; classObj = Class.forName("java.lang.String");//返回与带有给定字符串名的类或接口相关联的 Class 对象。(API) System.out.println(classObj.getSuperclass().getName());//父类名 Class[] classList=classObj.getInterfaces();//接口列表 for (Class obj: classList) { System.out.println(obj.getName());//实现的接口 } //Result java.lang.Object 默认所有的类都是继承Object类 // java.io.Serializable // java.lang.Comparable // java.lang.CharSequence }
上方这些在Class的API都有详细介绍
通过反射实例化一个类的对象: 两种方式使用类的默认构造方法,指定一个构造方法
public class Test {    public static void main(String[] args) throws Exception {        //----------------------------------        //第一种        Class
classObj = null; classObj = Class.forName("com.jctl.cloud.test.Student");//返回与带有给定字符串名的类或接口相关联的 Class 对象。(API) Student student = (Student) classObj.newInstance(); student.setName("明"); System.out.println(student.toString()); //第二种 Constructor
cons[] = classObj.getConstructors();//获取所有的构造方法 for (Constructor constructor: cons) { Class
[] params= constructor.getParameterTypes(); for (Class param : params) { System.out.println(param.getName()); } System.out.println("****************************");//打印几次说明有几个构造方法啊 } Student student1 = (Student) cons[1].newInstance("marry",10); System.out.println(student1.toString()); }}class Student{ private String name; private Integer age; public Student() { } public Student(String name, Integer age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; }}

控制台:

 
  //Result    Student{name='明', age=null}   ****************************   java.lang.String   java.lang.Integer   ****************************   Student{name='marry', age=10}
 

 

获取类的全部属性
public static void main(String[] args) throws Exception {        //----------------------------------        //第一种        Class
classObj = null; classObj = Class.forName("com.jctl.cloud.test.Student");//返回与带有给定字符串名的类或接口相关联的 Class 对象。(API) Field[] fields= classObj.getDeclaredFields(); for (Field field: fields) { //修饰符 + 类型 + 名字 System.out.println(Modifier.toString(field.getModifiers()) +" "+field.getType().getSimpleName()+" "+field.getName()); } } //console

修改类的属性无视private
public static void main(String[] args) throws Exception {        //----------------------------------        //第一种        Class
classObj = null; classObj = Class.forName("com.jctl.cloud.test.Student");//返回与带有给定字符串名的类或接口相关联的 Class 对象。(API) Object object=classObj.newInstance(); Field field = classObj.getDeclaredField("name");// 返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段。 field.setAccessible(true); field.set(object, "xiaomei"); System.out.println(field.get(object));// field.get(Object obj) 反回指定对象上此 Field 表示的字段的值。 } //console

 获取类的全部方法

  先给上面的Student类增加一个方法

public void doHomeWork(){        System.out.println(this.name+"开始写作业了!");    }
public void doHomeWork() {
System.out.println("开始写作业了!"); }
 

 

public static void main(String[] args) throws Exception {        //----------------------------------        //第一种        Class
classObj = null; classObj = Class.forName("com.jctl.cloud.test.Student");//返回与带有给定字符串名的类或接口相关联的 Class 对象。(API) Method[] methods = classObj.getDeclaredMethods(); for (Method method : methods) { System.out.println( Modifier.toString(method.getModifiers())+" "//修饰符 +method.getGenericReturnType().toString()+" "+//返回值 method.getName()) ;//方法名 } //public class java.lang.String toString // public class java.lang.String getName //public void setName // public class java.lang.Integer getAge // public void setAge //public void doHomeWork}

  直接调用类的方法:

public static void main(String[] args) throws Exception {        Class
classObj = null; classObj = Class.forName("com.jctl.cloud.test.Student");//返回与带有给定字符串名的类或接口相关联的 Class 对象。(API) Method methods = classObj.getMethod("doHomeWork"); methods.invoke(classObj.newInstance()); //控制台 null开始写作业了! Method methods1 = classObj.getMethod("doHomeWork",String.class); methods1.invoke(classObj.newInstance(),"\"小明\"");      //控制台 小明开始写作业了! }

 

 写了这些反射在java中怎么使用和基本用法,总得做点什么,下一篇反射在代理模式中的应用----------->>>

  

转载于:https://www.cnblogs.com/lewskay/p/7216968.html

你可能感兴趣的文章
mysql基于mysqlslap的压力测试
查看>>
zencart中query_factory.php中连接mysql次数
查看>>
fail2ban 保护linux安全(转载)已用于生产环境
查看>>
表格元素的添加和删除,计算器,全选全不反选
查看>>
数据约束
查看>>
网络营销第七课(1):制定SEO计划(网站相关数据分析)
查看>>
nginx rewrite 参数和例子
查看>>
mysqldump命令
查看>>
github上传代码步骤
查看>>
利用express搭建一个restful api 服务器
查看>>
(转)调整.NET控件WebBrowser的默认浏览器内核版本
查看>>
[导入]让你的WAP网站有更好的兼容性
查看>>
.NET Exceptionless 本地部署踩坑记录
查看>>
航电OJ-2544最短路
查看>>
CF772E Verifying Kingdom
查看>>
雨林木风U盘装系统综合教程
查看>>
V-by-one
查看>>
让我欲罢不能的node.js
查看>>
python3基础知识学习记录
查看>>
10年.NET老程序员推荐的7个开发类工具
查看>>