java基础知识之注解、反射(一)
前言
此博客为供个人学习总结备用,如有错误请指正。
正文
Annotation(注解)
java自带的注解包含以下三个:
1.@Override 注解表示重写父类的方法
2.@Deprecated 声明被注解的方法或字段等废弃,不建议使用
3.@SuppressWarnings 抑制所有的警告
其中@Deprecated和@SuppressWarnings注解可以配置多个参数,用来表达不同的对象范围,如@SuppressWarnings({“unchecked”,“unused”})表示抑制警告。
点开SuppressWarnings 注解源代码查看:
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {String[] value();//表示注解定义时传递的参数
}
@SuppressWarnings 注解是使用@interface定义来定义的,而该注解又被java元注解所修饰,元注解表示用来解释注解的注解,常见@Target和@Retention使用:
Target注解表示注解能配置的范围,如:
@Target({TYPE, FIELD, METHOD})表示注解配置范围为type(类型)、field(字段)、METHOD(方法)@Retention用于描述注解的生命周期如:@Retention(RetentionPolicy.RUNTIME)SOURCE表示在源文件中有效CLASS表示在CLASS文件有效RUNTIME表示运行时有效,可以被反射机制读取
下面实现一个简单的自定义注解:
首先使用@interface定义注解:
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;import static java.lang.annotation.ElementType.*;@Retention(RetentionPolicy.RUNTIME)//运行时有效
@Target(value={FIELD, METHOD, TYPE})//配置了注解的使用范围,字段、方法和类型
public @interface MyAnnotation {String[] value();//只有一个值的时候一般命名为value(),且注解传值时可省略value=int age() default -1;//不传值时age相当于不存在未定义,不强求传值String StudentName() default "小明";//默认值小明
}
然后在类中进行使用:
import java.util.Date;public class Demo01 {//使用自定义注解并传值@MyAnnotation(value = {"d","f"}, StudentName = "小兰")private int i;//@Override注解表示重写父类的方法@Overridepublic String toString(){return i +"";}//表示废弃,不建议使用@Deprecatedpublic static void test(){System.out.println("test");}//抑制所有的警告,参数可以配置多个,如://@SuppressWarnings("all")@SuppressWarnings({"all","unused"})public static void main(String[] args) {Date date = new Date();test();}
}
可能到这里有些迷惑,自定义注解然后呢,有个毛用啊。这就要涉及到反射了,在反射中取到注解注入的信息,能够减少开发的工作量。下面再举个注解的例子:
自定义两个注解,Table和Field用来对数据库表名和字段产生对应关系。
SxtTable注解:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface SxtTable {String value();//用来接收对应数据库表名
}
SxtField注解:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SxtField {String columnName();//对应表字段名String type();//字段类型int length();//长度
}
接下来定义Student类,包括学号、姓名和年龄三个属性,并生成get、set方法:
@SxtTable("tb_student")
public class SxtStudent {public SxtStudent() {}public SxtStudent(int id) {this.id = id;}@SxtField(columnName = "id", type = "int", length = 10)private int id;@SxtField(columnName = "sname", type = "nvarchar", length = 50)private String StudentName;@SxtField(columnName = "age", type = "int", length = 10)private int age;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getStudentName() {return StudentName;}public void setStudentName(String studentName) {StudentName = studentName;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}
那么现在已经将学生类通过注解对应到数据库了,由@SxtTable(“tb_student”)知对应表名tb_student,由@SxtField看到学生类的各属性分别对应表字段。
接下来就可以通过反射读取注解进行相应的操作了,那就有可能插入学生信息到表就像mybatis插入数据那么方便了,注解的价值就得以体现。
注解怎么通过反射进行获取?
反射
反射暂时也说不出个所以然,来看看大概怎么使用吧:
//加载类对象
Class clazz = Class.forName("annotation.testAnnotation.SxtStudent");
System.out.println(clazz);
//获取类的属性
Field f01 = clazz.getField("id");//只能获取到公有的属性
System.out.println(f01);
Field f02 = clazz.getDeclaredField("id");//获取所有声明的属性
System.out.println(f02);
//获取到所以属性
Field[] fields01 = clazz.getFields();//同样只能获取公开的属性
Field[] fields = clazz.getDeclaredFields();//获取所有声明的属性
for (Field temp : fields) {System.out.println("属性:" + temp);
}
//获得类的方法,和属性类似
//第二个参数传递方法参数类型,用以区分当重写方法名字相同的情况
Method m01 = clazz.getDeclaredMethod("setAge", int.class);//获得构造器信息
Constructor[] constructors = clazz.getDeclaredConstructors();
//获得无参构造器
Constructor constructor = clazz.getDeclaredConstructor(null);
//获取参数为int的构造器
Constructor constructor1 = clazz.getDeclaredConstructor(int.class);
System.out.println(constructor);//调用了SxtStudent无参的构造函数,
// 注意如果类中实现了有参构造器,调用方法会有异常,一般保留无参的构造函数
SxtStudent student = clazz.newInstance();
System.out.println(student);//动态使用构造器
Constructor<SxtStudent> c =clazz.getDeclaredConstructor(int.class);
SxtStudent s1 = c.newInstance(3);
System.out.println(s1.getId());//使用方法
SxtStudent s2 = clazz.newInstance();
Method m = clazz.getDeclaredMethod("setId", int.class);
m.invoke(s2, 5); //等价于s2.setId(7);
System.out.println(s2.getId());//直接设置属性的值
SxtStudent s3 = clazz.newInstance();
Field f = clazz.getDeclaredField("id");
f.setAccessible(true);//表示不做安全性检查,可以提交速度,看情况使用
f.set(s3,9);//跳过安全性检查才能直接设置私有属性的值
System.out.println(s3.getId());//------------------反射获取注解--------------------------
//获得类的所有有效注解
Class clazz = Class.forName("annotation.testAnnotation.SxtStudent");
Annotation[] annotations = clazz.getAnnotations();
for (Annotation annotation: annotations){System.out.println(annotation);
}
//获得指定注解
SxtTable table = (SxtTable) clazz.getAnnotation(SxtTable.class);
System.out.println(table.value());
//获得类属性的注解
Field f = clazz.getDeclaredField("id");
SxtField SxtField = f.getAnnotation(SxtField.class);
System.out.println(SxtField.columnName() + "---" + SxtField.type() + "---" + SxtField.length());
基础的使用大致就是这样,再说明一下注意点:
Class.forName(path) JVM会加载一个类的Class对象,并且同一个类只会有一个Class对象,多次加载的对象相同。
反射会影响程序性能,让程序变慢。setAccessible(true);//表示不做安全性检查,能提高反射的效率,利弊需自己衡量,在不需要安全检查的时候设置true能大大提高效率。
System.out.println("sdfj".getClass());
//"相同类型加载的类是一样的,JVM只会加载一个实例"
System.out.println("jdksll".getClass() == "sdfj".getClass());
//不同空间的Class实例不同
int[] j = {1,2,4};
int[][] k = new int[2][3];
System.out.println(j.getClass().hashCode() + "|" + k.getClass().hashCode());
java反射还能够获取到泛型,感兴趣可以自行搜索。
java基础知识之注解、反射(二)
java基础知识之注解、反射(一)相关推荐
- Java基础知识——类装载器与反射机制
类装载器ClassLoader 类装载器就是寻找类的字节码文件,并构造出类在JVM内部表示的对象组件. 类装载器把一个类装入JVM中,要经过三步: 1.装载:查找和导入Class文件: 2.链接:执行 ...
- java 反射类 spring_学习Spring必学的Java基础知识(1)----反射
引述要学习Spring框架的技术内幕,必须事先掌握一些基本的Java知识,正所谓"登高必自卑,涉远必自迩".以下几项Java知识和Spring框架息息相关,不可不学(我将通过一个系 ...
- 学习Spring必学的Java基础知识----反射
引述要学习Spring框架的技术内幕,必须事先掌握一些基本的Java知识,正所谓"登高必自卑,涉远必自迩".以下几项Java知识和Spring框架息息相关,不可不学(我将通过一个系 ...
- Java基础知识第二讲:Java开发手册/JVM/集合框架/异常体系/Java反射/语法知识/Java IO
Java基础知识第二讲(Java编程规范/JVM/集合框架/异常体系/Java反射/语法知识/Java IO/码出高效) 分享在java学习及工作中,常使用的一些基础知识,本文从JVM出发,讲解了JV ...
- JAVA基础知识学习全覆盖
文章目录 一.JAVA基础知识 1.一些基本概念 1.Stringbuffer 2.局部变量成员变量 3.反射机制 4.protect 5.pow(x,y) 6.final ,finally,fina ...
- Java基础知识 廖雪峰教程笔记
Java基础知识 Java基础知识 java简介 名词解释 运行Java程序 Java基本数据类型 模块 包装类型 记录类 异常处理 Java异常 使用Commons Logging 使用log4j ...
- Android开发必须掌握的Java基础知识和常见面试题
Java基础知识 面向对象特征 基本数据类型及装箱拆箱机制 String StringBuffer StringBuild final finally finalize 区别 static关键字 重写 ...
- Java基础知识(二)(Object类的常用方法、日期时间类、System类、StringBuilder类、包装类、Collection集合、Iterator迭代器、泛型、list集Set接口...)
文章目录 Java基础知识(二) 1.Object类的常用方法 1.1 toString方法 1.2 equals方法 1.3 Objects类 2.日期时间类 2.1 Date类 2.2 DateF ...
- 学习Spring必学的Java基础知识
学习Spring必学的Java基础知识(1)----反射 引述要学习Spring框架的技术内幕,必须事先掌握一些基本的Java知识,正所谓"登高必自卑,涉远必自迩".以下几项Jav ...
最新文章
- centos6.5环境DNS-本地DNS主从服务器bind的搭建
- 以后看下try,catch在C#下面的成本
- 导出toolStrip1中的图标
- delphi libeay32 各版本_Zbrush各版本合集
- Mybatis入门程序增删改查操作
- [js] 请使用 js 实现一个双向链表
- 如何把你的图标转换成WEB字体
- Freeswitch在内网,由服务器防火墙映射出来,IMSDROID作为被叫的问题
- 使用selenium爬取东航余票
- Android,App 常用图标尺寸规范
- 万用表使用_如何使用万用表
- 离散数学程序实现——求关系矩阵的自反和对称闭包——c
- 读书笔记(宏微观经济学)
- 数据库LATEST DETECTED DEADLOCK
- 热烈欢迎云南财经大学统计与数学学院院长石磊教授来芝诺数据视察指导工作
- c语言运行excel中vba程序,VBA代码在WPS上可运行,在EXCEL中报错
- 几种操作系统的基本特点
- SQL Server修改密码
- 价格时序预测-LSTM
- 大数据可视化陈为智慧树_智慧树知到大数据可视化见面课答案