java初学小结(3)

注解_反射_字节码_类运行机制_动态代理

  • 内置注解:
    @Override – 定义在java.lang.Override中,此注释只适用于修辞方法,表示一个方 法声明打算重写超类中的另一个方法声明。
    @Deprecated – 定义在java.lang.Deprecated中,此注释可用于修辞方法、属性、类 ,表示不鼓励程序员使用这样的元素,通常是因为它很危险或存在更 好的选择。
    @SuppressWarnings – 定义在java.lang.SuppressWarnings中,用来抑制编译时的警告信息 。 – 与前两个注释有所不同,你需要添加一个参数才能正确使用,这些参 数值都是已经定义好了的,我们选择性的使用就好了,参数如下:
    在这里插入图片描述
    – @SuppressWarnings(“unchecked”)
    – @SuppressWarnings(value={“unchecked”, “deprecation”})
  • 自定义注解:
    使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口 • 要点: – @interface用来声明一个注解 • 格式为: – public @interface 注解名 {定义体} – 其中的每一个方法实际上是声明了一个配置参数。 – 方法的名称就是参数的名称 – 返回值类型就是参数的类型(返回值类型只能是基本类型、Class、String、enum) – 可以通过default来声明参数的默认值。 – 如果只有一个参数成员,一般参数名为value
    • 注意: 注解元素必须要有值。我们定义注解元素时,经常使用空字符串、0作为默认值。 也经常使用负数(比如:-1)表示不存在的含义
/**
 * 自定义操作日志记录注解
 * 
 * @author ruoyi
 *
 */
@Target({ ElementType.PARAMETER, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Log
{
    /** 模块 */
    String title() default "";

    /** 功能 */
    String action() default "";

    /** 渠道 */
    String channel() default OperatorType.MANAGE;

    /** 是否保存请求的参数 */
    boolean isSaveRequestData() default true;

}

元注解:
元注解的作用就是负责注解其他注解。 Java定义了4个标准的 meta-annotation类型,它们被用来提供对其它 annotation 类型作说明。
• 这些类型和它们所支持的类在java.lang.annotation包中可以 找到
– @Target
– @Retention
– @Documented
– @Inherited

– @Target 作用: – 用于描述注解的使用范围(即:被描述的注解可以用在什么地方)
在这里插入图片描述
– @Target(value=ElementType.TYPE)

– @Retention 作用: – 表示需要在什么级别保存该注释信息,用于描述注解的生命周期
在这里插入图片描述
自定义注解的使用:

/**
     * 修改用户
     */
    @RequiresPermissions("system:user:edit")
    @Log(title = "用户管理", action = BusinessType.UPDATE)
    @GetMapping("/edit/{userId}")
    public String edit(@PathVariable("userId") Long userId, Model model)
    {
        User user = userService.selectUserById(userId);
        List<Role> roles = roleService.selectRolesByUserId(userId);
        List<Post> posts = postService.selectPostsByUserId(userId);
        model.addAttribute("roles", roles);
        model.addAttribute("posts", posts);
        model.addAttribute("user", user);
        return prefix + "/edit";
    }
  • 自定义注解的场景及实现:
    登陆、权限拦截、日志处理,以及各种 Java 框架,如 Spring,Hibernate,JUnit ,提到注解就不能不说反射,Java 自定义注解是通过运行时靠反射获取注解。实际开发中,例如我们要获取某个方法的调用日志,可以通过 AOP(动态代理机制)给方法添加切面,通过反射来获取方法包含的注解,如果包含日志注解,就进行日志记录。反射的实现在 Java 应用层面上讲,是通过对 Class 对象的操作实现的,Class 对象为我们提供了一系列方法对类进行操作。在 JVM 这个角度来说,Class 文件是一组以 8 位字节为基础单位的二进制流,各个数据项目按严格的顺序紧凑的排列在 Class 文件中,里面包含了类、方法、字段等等相关数据。通过对 Class 数据流的处理我们即可得到字段、方法等数据。

反射机制:class对象获取、动态操作(构造器、方法、属性)、
动态语言 – 程序运行时,可以改变程序结构或变量类型。典型的语言: • Python、ruby、javascript等。 • 如下javascript代码:
• C, C++, JAVA不是动态语言,JAVA可以称之为“准动态语 言”。但是JAVA有一定的动态性,我们可以利用反射机制、 字节码操作获得类似动态语言的特性。
• JAVA的动态性让编程的时候更加灵活!
反射机制 – 指的是可以于运行时加载、探知、使用编译期间完全未知的类。 – 程序在运行状态中,可以动态加载一个只有名称的类,对于任意一个 已加载的类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;
Class c = Class. forName (“com.bjsxt.test.User”);
– 加载完类之后,在堆内存中,就产生了一个 Class 类型的对象(一个 类只有一个 Class 对象),这个对象就包含了完整的类的结构信息。 我们可以通过这个对象看到类的结构。这个对象就像一面镜子,透过 这个镜子看到类的结构,所以,我们形象的称之为:反射
• java.lang.Class类十分特殊,用来表示java中类型 (class/interface/enum/annotation/primitive type/void)本 身。
– Class类的对象包含了某个被加载类的结构。一个被加载的类对应一个 Class对象。 – 当一个class被加载,或当加载器(class loader)的defineClass()被 JVM调用,JVM 便自动产生一个Class 对象。
• Class类是Reflection的根源。 – 针对任何您想动态加载、运行的类,唯有先获得相应的Class 对象

获取Class对象的获取方式:
• 运用 对象.getClass()
•运用 Class.forName()(最常被使用)
• 运用 类.class 语法

反射操作泛型:
• Java采用泛型擦除的机制来引入泛型。Java中的泛型仅仅是给编译器javac使用的,确保数据 的安全性和免去强制类型转换的麻烦。但是,一旦编译完成,所有的和泛型有关的类型全部 擦除。
• 为了通过反射操作这些类型以迎合实际开发的需要,Java就新增了ParameterizedType, GenericArrayType,TypeVariable 和WildcardType几种类型来代表不能被归一到Class 类中的类型但是又和原始类型齐名的类型。
• ParameterizedType: 表示一种参数化的类型,比如Collection
• GenericArrayType: 表示一种元素类型是参数化类型或者类型变量的数组类型
• TypeVariable: 是各种类型变量的公共父接口
• WildcardType: 代表一种通配符类型表达式,比如?, ? extends Number, ? super Integer【 wildcard是一个单词:就是“通配符”】

反射机制的优缺点:
优点:

运行期类型的判断,动态类加载,动态代理使用反射。

缺点:

性能是一个问题,反射相当于一系列解释操作,通知jvm要做的事情,性能比直接的java代码要慢很多。

反射的适用场景是什么?

1).Java的反射机制在做基础框架的时候非常有用,有一句话这么说来着:反射机制是很多Java框架的基石。而一般应用层面很少用,不过这种东西,现在很多开源框架基本都已经给你封装好了,自己基本用不着写。典型的除了Hibernate之外,还有Spring也用到很多反射机制。经典的就是在xml文件或者properties里面写好了配置,然后在Java类里面解析xml或properties里面的内容,得到一个字符串,然后用反射机制,根据这个字符串获得某个类的Class实例,这样就可以动态配置一些东西,不用每一次都要在代码里面去new或者做其他的事情,以后要改的话直接改配置文件,代码维护起来就很方便了,同时有时候要适应某些需求,Java类里面不一定能直接调用另外的方法,这时候也可以通过反射机制来实现。
总的来说,自己写的很少,具体什么时候要用那要看需求,反射机制无非就是根据一个String来得到你要的实体对象,然后调用它原来的东西。但是如果是要自己写框架的话,那就会用得比较多了。

2)当你做一个软件可以安装插件的功能,你连插件的类型名称都不知道,你怎么实例化这个对象呢?因为程序是支持插件的(第三方的),在开发的时候并不知道 。所以无法在代码中 New出来 ,但反射可以,通过反射,动态加载程序集,然后读出类,检查标记之后再实例化对象,就可以获得正确的类实例。

3)在编码阶段不知道那个类名,要在运行期从配置文件读取类名, 这时候就没有办法硬编码new ClassName(),而必须用到反射才能创建这个对象.反射的目的就是为了扩展未知的应用。

JVM核心机制 类加载器基础:
1.什么是机器码?
机器码是机器能够通过内置的指令系统识别的指令编码。

2.什么是字节码?
字节码(ByteCode)是一种中间状态的二进制文件(中间码),就是我们常见的*.class文件。
为什么说它是中间码?因为字节码处于源程序(如java语言的.java文件,JRuby的*.rb文件)和机器码之间,是一个中间状态。

3.为什么要用字节码?
平台无关性:我们是否还记得当初学习java时候有句著名的口号–一次编写,到处运行。java语言之所以能运行在各个平台上,与各个平台上运行的虚拟机有很大关系。因为这些虚拟机都能够载入和执行同一种与平台无关的程序存储格式–字节码(ByteCod),所以字节码是平台无关性的基石。
在这里插入图片描述
语言无关性–可能很多人认为java虚拟机就是专门为java语言设计的,其实这种理解是错误的。java虚拟机在设计之初,就充分考虑了让其他语言在java虚拟机上运行的可能性,而字节码作为一种中间状态的文件,能够建立各种语言编写的源程序与虚拟机之间的桥梁(源程序–>编译器–>字节码–>虚拟机),所以字节码也是语言无关性的基石。
以上两个无关性基石,共同确立了字节码的地位。

  • Java程序具体执行的过程:
    Java程序具体执行的过程
    执行引擎内容参:https://blog.csdn.net/shahuhubao/article/details/81386622

  • 运行时数据区:
    运行时数据区
    4.javac编译器
    javac编译器,属于前端编译器的一种,是专门针对java语言而设计的一款编译器,它是由java语言编写的程序,负责把*.java文件转变成.class文件.

动态代理:
JDK 和CGLIB,Javassist,ASM都可以实现动态代理。基于字节码进行操作。

  • spring的动态代理:
    JDK动态代理,基于接口(默认代理模式),CGLIB动态代理(若要使用需要进行配置)。
    JDK动态代理是由java JDK提供
    其缺点是只能为接口创建代理,返回的代理对象也只能转到某个接口类型
    CGLIB动态大力是由是由第三方库cglib提供,
    CGLIB的实现机制与JDK的实现机制不同,它是通过继承实现的,它也是动态的创建一个类,但这个类的父类是被代理类
    如何将代理模式由默认的JDK切换到CGLIB
    配置aop <aop:config proxy-target-class=“true”> true使用CGLIB产生代理对象 false 使用jdk 默认false。

Java动态代理机制详解参:https://blog.csdn.net/luanlouis/article/details/24589193

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值