首页 > 其他 > 详细

注解和反射

时间:2021-03-29 17:51:06      阅读:26      评论:0      收藏:0      [点我收藏+]

Java.Annotation:注解

1. 什么是注解

  1. Annotation 是从JDK5.0开始引入的新技术
  2. Annotation的作用
    1. 不是程序本身,可以对程序作出解释(与注释comment相同)
    2. 可以被其他程序(如编译器)读取
  3. Annotation的个数:
    1. 以“@注释名“的形式在代码中存在
  4. Annotation可以在哪里使用
    1. 可以附加在package、class、method、field上面,相等于给他们添加了额外的辅助信息,我们可以通过反射机制编程实现对这些元数据的访问

内置注解

  1. @Override:定义在java.lang.Override中,此注释值适用于修辞方法,表示一个方法声明打算重写超类中的另一个方法声明

  2. @Deprecated:定义在java.lang.Deprecated中,此注释可以用于修辞方法,属性,类,表示等不鼓励程序员使用这样的元素,通常是因为它很危险或者存在更好的选择

  3. @SuppressWarnings:定义java.lang.SuppressWarnings中,用来抑制编译时的警告信息

    与前两个注释有所不同,需要添加一个参数才能正确的使用,这些参数都是定义好的,我们有选择的使用就好了

    例如:

    @SuppressWarning("all")
    @SuppressWarning("unchecked")
    @SuppressWarning(value={"unchecked","deprecation"})
    

元注解

作用:负责注解其他注解(是注解的注解),java定义了4个标准的meta-annotation类型,他们被用来提供对其annotation类型作说明

这些类型和他们所支持的类在java.lang.annotation包中科院找到。(@Target,@Retention,@Documented,@Inherited)

  1. @Target:用于描述注解的使用范围(被描述的注解科院用在什么地方)
  2. @Retention :表示需要在什么级别保存该注释信息,用于描述注解的生命周期(SOURCE【源代码时有用】<CLASS【class时有用】<RUNTIME【运行时有用】)注解在什么时候有用
  3. @Documented:说明该注解将被包含在Javadoc中
  4. @Inherited:说明子类科院继承父类中的该注解
package com.zhou3.Annotation;

import java.lang.annotation.*;

/*
测试元注解
 */
@MyAnnotation
public class Test01 {
    public static void main(String[] args) {

    }
    @MyAnnotation
    public void test(){

    }
}

//定义一个注解
// Target定义的注解想要放在那个地方(方法,类)
@Target(value = {ElementType.METHOD,ElementType.TYPE})
//Retention在什么时候还有效(运行时)
// runtime>class>sources
@Retention(value = RetentionPolicy.RUNTIME)
//表示是否将注解生成到javaDoc文档中
@Documented
//表示子类可以继承父类的注解
@Inherited
@interface MyAnnotation{

}

自定义注解

使用@interface 自定义注解时,自动继承了java.lang.annotation接口

注意点:

  1. @interface用来声明一个注解,格式:public @interface 注解名 {定义内容}
  2. 其中的每一个方法实际上是声明了一个配置参数
  3. 方法的名称就是参数的名称
  4. 返回值类型就是参数的类型,返回值只能是(基本类型,Class,String,enum)
  5. 可以通过default来声明参数的默认值
  6. 如果只有一次参数成员,一般参数名为value(因为只有value才可以省略)
  7. 注解元素必须要有值,我们定义注解元素时,经常使用空字符串,0作为默认值

2. 反射机制

java.Reflection包下

是java语言成为准动态语言的基础

注意:(这个Class有点像一个类的母版)

  1. 一个类在内存中只有一个Class对象

  2. 一个类被加载后,类的整个结构都会被封装在Class中

1. 静态语言和动态语言

  1. 动态语言:

    1. 是一类在运行时,可以改变器结构的语言(代码在运行时可以根据某些条件改变自身的结构)

    2. 主要的动态语言:Object-C、C#、JavaScript、PHP、Python

  2. 静态语言:

    1. 与动态语言对应,运行时结构不可变的语言就是静态语言,如Java、c、c++

    2. Java不是动态语言,但是Java可以称之为“准动态语言”。即Java有一定的动态性。我们可以利用反射机制获得类似动态语言的特性。而这种动态性让编程更加灵活

2. java Reflection

  1. Reflection(反射)是Java被视为动态语言的关键,反射机制允许程序在执行期间,借助Reflection API获得任何类的内部信息,并能直接操作任意对象的内部属性及方法

  2. 加载完类之后,砸死堆内存的方法区就产生了一个Class类型的对象(一个类只有一个Class对象),这个对象包含了完整的类的结构信息。我们可以通过这个对象看到类的结构。这个对象就像一面镜子,透过这个镜子看到类的结构,所有,我们将其形象的称之为反射

3. 反射机制提供的功能

  1. 运行时判断任意一个对象所属的类
  2. 运行时构造任意一个类的对象
  3. 运行时判断任意一个类锁具有的成员变量和方法
  4. 运行时获取泛型信息
  5. 运行时调用任意一个对象的成员变量和方法
  6. 运行时处理注解
  7. 生成动态代理

4. 反射的主要API

java.lang.Class:代表一个类
java.lang.reflect.Method:代表类的方法
java.lang.reflect.Field:代表类的变量
java.lang.reflect.Constructor:代表类构造器

5. Class类

对象在照镜子之后可以得到的信息:某个类的属性、方法和构造器、某个类到底实现了那些接口,对于每个类而言,JRE都为其保留一个不变的Class类型的对象。一个Clas对象包含了特点某个结构(class/interface/enum/annotation/primitive type/void/[])的有关信息

  1. Class本身也是一个类
  2. Class对象只能由系统建立对象
  3. 一个加载的类在JVM中只会有一个Class实例
  4. 一个Class对象对于的是一个加载到JVM中的一个.class文件
  5. 每个类的实例都会记得字节是由那个Class所生成
  6. 通过Class可以完整地得到一个类中的所有被加载的结构
  7. Class类是Reflection的根源,针对任何你想动态加载、运行的类,唯有先获得相应的Class对象
方法名 功能说明
static ClassforName(String name) 返回指定类名name的Class对象
getName() 返回此Class对象所表示的实体(类,接口,数组类或void)的名称
Class getSuperClass() 返回当前Class对象的父类的Class对象
Class[] interfaces() 获取当前Class对象的接口
Class getClassLoader() 返回该类的类加载器
Class []getConstructors() 返回一个包含某些Constructor对象的数组
Method getMothed(String name,Class.. T) 返回一个Method对象,此对象的形参类型为paramType
Object newInstance() 调用缺省构造函数,返回Class对象的一个实例
Field[] getDeclaredFields() 返回Field对象的一个数组
//获得Class对象的几种方式
//1. 通过对象获得
Person person1 = new Person();
Class c1 = person1.getClass();
//2. forname方法获得
Class c2 = Class.forname("com.zhou3.reflection.Person")    
//3. 通过类名.class获得
Class c3 = Person.class;    
//4. 基本内置类型的包装类都有一个Type属性
Class c4 = Integer.TYPE;    
    
//那些类有Class
public static void main(String[] args){
    Class c1 = Object.class;    //类
    Class c2 = Comparable.class;//接口
    Class c3 = String[].class;  //一维数组
    Class c4 = int[][].class;   //二维数组
    Class c5 = Ovdrride.class;  //注解
    Class c6 = ElementType.class;//枚举类型
    Class c7 = Integer.class;    //基本数据类型
    Class c8 = void.class;       //void
    Class c9 = Class.class;      //Class
}

6. 反射可以做什么

可以对类中的方法或属性进行操作

可以通过关闭安全检测= 属性或方法.setAccessible(true) =这种方式类提高反射的效率

//获取Class对象
Class c1 = Class.forname("com.zhou.reflection.User");

//构造对象
User user = (User)c1.newInstance();//调用了无参构造器
System.out.println(user);
//通过构造器构造对象
Constructor constructor = c1.getDeclaredConstructor(String.class,int.class,int.class);
User user2 = (User)construct.newInstance("反射",01,18)
//通过反射调用普通方法
Method setName = c1.getDeclaredMethod("setName",String.class);
//激活
//(对象,"方法的值")
setName.invoke(user1,"小明");



//不能直接操作私有属性,我们需要关闭程序的安全检测才可以直接操作私有属性,属性或方法.setAccessible(true)
name.setAccessible(true);

注解和反射

原文:https://www.cnblogs.com/zhoushuaiyi/p/14592648.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!