Java反射机制

反射机制是java的动态机制,可以在程序"运行期间"再确定实例化对象,方法调用,属性操作等。

反射机制可以提高代码的灵活度,但是会带来较多的系统开销和较低的运行效率,因此不能过度依赖。

Class类

Class类称为类的类对象。
JVM加载一个类的class文件时,就会创建一个Class实例与该类绑定。因此每个被加载的
类都有且只有一个Class实例,这个实例就是该加载的类的类对象。
通过一个类的类对象我们可以获取这个类的一切信息(类名,属性,方法,构造器等)从而在
程序运行期间进行相关的操作

因此反射第一步就是要获取操作的类的类对象。而获取方式有三种:

1:类名.class

2:Class.forName(String className)

3:ClassLoader类加载器形式获取

1:类名.class

Class cls = String.class;
Class cls = int.class;

获取String的类对象


Class cls = String.class;
Class cls = ArrayList.class;
Class cls = Class.forName("java.lang.String");

2:Class.forName(String className)

Class cls = Class.forName(“java.lang.String”);//参数需要是完全限定名:包名.类名
注意:基本类型不支持此种方式获取类对象

Scanner scanner = new Scanner(System.in);
System.out.println("请输入要加载的类的名字:");
String className = scanner.nextLine();
Class cls = Class.forName(className);

获取完全限定名:包名.类名

String name = cls.getName();
System.out.println(name);

仅获取类名

name = cls.getSimpleName();//仅获取类名
System.out.println(name);

获取包名

String packageName = cls.getPackage().getName();
System.out.println("包名:"+packageName);

获取String类的所有公开方法(包含从超类继承的方法)

 Method[] methods = cls.getMethods();

//获取String类的所有公开方法(包含从超类继承的方法)

Method[] methods = cls.getMethods();

获取本类自己定义的方法(包含私有方法)

Method[] methods = cls.getDeclaredMethods();

使用反射机制实例化对象

1获取要实例化对象的类的类对象

Class cls = Class.forName("java.util.ArrayList");
Class cls = Class.forName(className);Scanner scanner = new Scanner(System.in);
System.out.println("请输入类名:");
String className = scanner.nextLine();
Class cls = Class.forName(className);

2调用Class的newInstance()来调用无参构造器

Object obj = cls.newInstance();
System.out.println(obj);

使用指定的构造器实例化对象

1加载类对象

Class cls = Class.forName("reflect.Person");

2通过类对象获取指定的有参构造器:Person(String,int)

Constructor c = cls.getConstructor();//不传参获取的就是无参构造器
Constructor c = cls.getConstructor(String.class,int.class);
Object obj = c.newInstance("王五",66);//new Person("王五",66);
System.out.println(obj);

利用反射机制调用方法

public class ReflectDemo4 {public static void main(String[] args) throws Exception {Person p = new Person();p.watchTV();Scanner scanner = new Scanner(System.in);System.out.println("请输入类名:");String className = scanner.nextLine();System.out.println("请输入方法名:");String methodName = scanner.nextLine();//1实例化//1.1加载类对象
//        Class cls = Class.forName("reflect.Person");Class cls = Class.forName(className);//1.2实例化Object obj = cls.newInstance();//Object obj = new Person();//2调用方法//2.1通过类对象获取要调用的方法
//        Method method = cls.getMethod("watchTV");Method method = cls.getMethod(methodName);//2.2通过方法对象执行该方法method.invoke(obj);//obj.watchTV()   前提是obj表示的是一个Person对象}
}

调用有参方法

public class ReflectDemo5 {public static void main(String[] args) throws Exception {Class cls = Class.forName("reflect.Person");Object obj = cls.newInstance();//public void say(String info){Method method = cls.getMethod("say",String.class);method.invoke(obj,"你好!");//p.say("你好!");//public void say(String info,int count){Method method2 = cls.getMethod("say",String.class,int.class);//调用方法method2.invoke(obj,"嘿嘿",5);//p.say("嘿嘿",5)}
}

获取私有方法

public class ReflectDemo6 {public static void main(String[] args)throws Exception {
//        Person p = new Person();
//        p.hehe();//编译不通过!hehe是私有方法!Class cls = Class.forName("reflect.Person");Object obj = cls.newInstance();/*Class的方法:getMethod(),getMethods()都只能获取到类对象表示的类的公开方法*/
//        Method method = cls.getMethod("hehe");Method method = cls.getDeclaredMethod("hehe");method.setAccessible(true);//强行打开访问权限method.invoke(obj);//p.hehe();method.setAccessible(false);}
}

反射机制访问注解

public class ReflectDemo7 {public static void main(String[] args) throws Exception {Class cls = Class.forName("reflect.Person");/*Class,Method等常用的反射对象都提供了一个方法:boolean isAnnotationPresent(Class cls)用于判断是否被参数指定的注解标注过(参数为注解的类对象)*///cls所表示的类Person是否被注解@AutoRunClass标注过boolean flag = cls.isAnnotationPresent(AutoRunClass.class);if(flag){System.out.println("被标注了!");}else{System.out.println("没有被标注!");}}
}

获取注解中的参数

public class ReflectDemo8 {public static void main(String[] args) throws Exception {Class cls = Class.forName("reflect.Person");Method method = cls.getMethod("sayHello");if(method.isAnnotationPresent(AutoRunMethod.class)){//获取该方法上的注解@AutoRunMethodAutoRunMethod arm = method.getAnnotation(AutoRunMethod.class);//通过注解对象获取value参数的值int value = arm.value();System.out.println(value);}}
}

Person类

@AutoRunClass
public class Person {private String name = "张三";private int age = 22;public Person(){}public Person(String name, int age) {this.name = name;this.age = age;}@AutoRunMethod(5)public void sayHello(){System.out.println(name+":hello!");}public void sayHi(){System.out.println(name+":hi!");}@AutoRunMethodpublic void dance(){System.out.println(name+"正在跳舞");}public void sing(){System.out.println(name+"正在唱歌");}@AutoRunMethod(3)public void watchTV(){System.out.println(name+"正在看电视");}public void playGame(){System.out.println(name+"正在打游戏");}public void say(String info){System.out.println(name+"说:"+info);}public void say(String info,int count){for(int i=0;i<count;i++){System.out.println(name+"说:"+info);}}private void hehe(){System.out.println("我是Person的私有方法!!!");}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';}
}

注解

注解被大量应用与反射中,可以辅助反射机制做更多灵活的操作。

后期使用的框架基本都是使用注解进行配置的。

在注解上我们有两个常用的注解用来说明当前注解的相关特性:

@Target:用于说明我们定义的注解可以被应用到哪里。

该注解可以传递的参数为ElementType类型,用来表示可标注的位置。

常见的有:

  • ElementType.TYPE:在类上用

  • ElementType.METHOD:在方法上

  • ElementType.FIELD:在属性上用

如果不指定@Target,则当前注解可以被应用在任何注解可使用的位置上。

@Retention:当前注解的保留级别,有三个可选值

RetentionPolicy.SOURCE:当前注解仅保留在源代码中,编译后的字节码文件中没有该注解

RetentionPolicy.CLASS:保留到编译后的字节码文件中,但是反射机制不可访问

RetentionPolicy.RUNTIME:保留到字节码中且反射机制可以访问

不指定时,默认保留级别为CLASS

注解中定义参数的语法:

类型 参数名() [default 默认值]; 注:[]中的内容可写,可不写。

只有一个参数时:

如果当前注解只有一个参数时,那么参数名应当叫value.
此时当我们在外面使用该注解时,可以使用:
@AutoRunMethod(3)
进行传参。此时注解中value的值为3
如果该参数名不叫value,例如,定义时如下:
public @interface AutoRunMethod{int num();
}
此时当我们在外面使用该注解时,可以使用:
@AutoRunMethod(num=3)       语法要求:传参时格式为:参数名=参数值
进行传参。此时注解中num的值为3
只有参数名叫value时,传递参数才可以将参数名忽略。

当有多个参数时,

例如,定义时如下:
public @interface AutoRunMethod{int value();String name();
}

使用注解传递参数时,参数名都不可以忽略,必须写为name=value的格式,且顺序无所谓。

例如:
@AutoRunMethod(value=1,name="张三")
@AutoRunMethod(name="张三",value=1)
以上都正确

参数可以使用default指定默认值,那么在使用注解时。可以不指定该参数的值,此时使用默认值

 public @interface AutoRunMethod{int value() default 1;}使用该注解时:@AutoRunMethod(3)此时value的值为3@AutoRunMethod此时value的值为1(默认值)

Java反射机制与注解相关推荐

  1. 反射 字段_详解面试中常考的 Java 反射机制

    反射(Reflection) 是 Java 程序开发语言的特征之一,它允许运行中的 Java 程序对自身进行检查,或者说"自审",并能直接操作程序的内部属性和方法. 反射是一项高级 ...

  2. java基础-java反射机制

    2019独角兽企业重金招聘Python工程师标准>>> 引述要学习Spring框架的技术内幕,必须事先掌握一些基本的Java知识,正所谓"登高必自卑,涉远必自迩" ...

  3. java反射机制和junit的使用

    1. 反射的原理 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性:这种动态获取信息以及动态调用对象方法的功能称为jav ...

  4. java反射机制详解_Java反射机制详解

    Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反 ...

  5. Java反射机制的基本概念与使用_Java进阶之reflection(反射机制)——反射概念与基础...

    反射机制是Java动态性之一,而说到动态性首先得了解动态语言.那么何为动态语言? 一.动态语言 动态语言,是指程序在运行时可以改变其结构:新的函数可以引进,已有的函数可以被删除等结构上的变化.比如常见 ...

  6. Java反射机制Reflection

    Java反射机制 1 .class文件 2 Class类 3 Class类与反射机制 4 Java反射机制的类库支持及简介 5 反射机制的定义与应用 6 反射机制Demo Java反射机制demo(一 ...

  7. 12000+字Java反射,一起全面了解Java反射机制,为学习框架铺路

    文章目录 Java反射机制 理解Class类 获取Class类实例 类的加载过程 类加载器ClassLoader 创建运行时类的对象 获取运行时类的结构 调用运行时类的指定结构 动态代理 Java反射 ...

  8. Java反射机制概念及应用场景

    Java反射机制概念及应用场景 Java的反射机制相信大家在平时的业务开发过程中应该很少使用到,但是在一些基础框架的搭建上应用非常广泛,今天简单的总结学习一下. 1. 什么是反射机制? Java反射机 ...

  9. Java反射机制API

    实现 Java 反射机制的类都位于 java.lang.reflect 包中,java.lang.Class 类是 Java 反射机制 API 中的核心类. java.lang.Class 类 jav ...

最新文章

  1. oracle 被另一用户锁定,Oracle报错记录被另外一个用户锁定的解决方案
  2. revit导出lumion插件_建筑工程BIM建模入门级教程——REVIT的几种渲染方式
  3. 《构建之法》读后感5
  4. 数学不好的人可以学python吗_哪些人适合学金融工程专业 数学不好能学吗
  5. Can not find the tag library descriptor for http://java.sun.com/jsp/jstl/
  6. 组播相对于单播和广播的优势
  7. 前百度主任架构师创业,两年融资千万美元,他说 AI 新药研发将迎来黄金十年...
  8. [妙味Ajax]第三课:AJAX跨域解决方案:JSONP
  9. 精通MVC3摘译(9)-过滤器
  10. sql服务器显示error,SQL server 2008 登陆服务器时提示错误233
  11. 2021东华杯misc详解
  12. vb 访问远程mysql_VB连接远程数据库
  13. BZOJ_5369_[Pkusc2018]最大前缀和_状压DP
  14. mac备份文件到windows
  15. 《数学之美》读后感:看数学之美,悟技术之道
  16. ​当AI搞起艺术来……
  17. 用C#开发一个 DNF文字版 【一】
  18. innobackupex全量恢复
  19. 新型冠状病毒传染模型SI、SIS、SIR、SEIR
  20. JAVA——基于控制台的购书系统

热门文章

  1. windows脚本实战
  2. VM安装操作系统提示CPU变频
  3. 全国中小学电脑制作比赛(大赛系列第11期)
  4. 【OpenGL ES】绘制魔方
  5. 【软件架构】为杠杆(利用率)架构设计软件
  6. 超级计算机搞笑图,搞笑图片幽默段子笑话:哥们,你的脚上下差距太大了吧,黑白分明...
  7. 2014年的那些碎碎念。
  8. 5分钟带你了解会员营销!
  9. Inside COM读书笔记-----包容和聚合
  10. [附源码]Java计算机毕业设计SSM宠物寄养预约系统