常用类
String:字符串
String:代表不可变的字符序列
String:字符串,使用一对 "" 引起来表示
① String声明为final的,不可被继承
② String实现了Serializable接口:表示字符串是支持序列化的。
实现了Comparable接口:表示String可以比较大小。
③ String内部定义了 final char[] value; 用于储存字符串数据
④ String:代表不可变的字符序列。简称:不可变性。
体现:
1.当对字符串重新赋值时,需要重新指定常量池中内存区域赋值,不能使用原有的value进行修改赋值。
2.当对现有的字符串进行连接操作时,也需要重新指定常量池中内存区域进行赋值,不能使用原有的value进行修改赋值。
3.当调用 String的replace() 方法时修改指定的字符或字符串时,也需要重新指定常量池中内存区域进行赋值,不能使用原有的value进行修改赋值。
⑤ 通过字面量(区别于 new)的方式给一个字符串赋值,此时的字符串值声明在方法区的字符串常量池当中。
字符串常量池中是不会存储两个相同内容的字符串,所以两个值一样的String对象的地址值也是一样的。
String s1 = "abc";//这种赋值方式:字面量定义。
.
.
String的实例化方式
方式一:通过字面量定义的方式
//此时的s1和s2的数据javaEE声明在方法区中的字符串常量池中。
String s1 = "javaEE";
String s2 = "javaEE";
方式二:通过new + 构造器的方式
//此时的s3和s4保存的地址值,是数据在堆空间中开辟空间以后对应的地址值。
String s3 = new String("javaEE");
String s4 = new String ("javaEE");
System.out.println(s1==s2);//true
System.out.println(s1==s3);//false
System.out.println(s1==s4);//false
System.out.println(s3==s4);//false
System.out.println("*******************");
Person p1 = new Person("Tom");
Person p2 = new Person("Tom");
System.out.println(p1.name == p2.name);//true
面试题:String s = new String("abc");方式创建对象,在内存中创建了几个对象?
两个:一个是堆空间中new的结构,一个是char[]对应的常量池中的数据:"abc"
.
.
String不同拼接操作的对比
结论:
1.常量与常量的拼接结果在常量池中。且常量池中不会存在相同内容的常量。
2.只要拼接中有一个是变量,结果就在堆中。
3.如果拼接的结果调用intern()方法,该方法的返回值就在常量池中。
4.final修饰的变量是常量,也存储在常量池中!!
.
.
String常用方法
int length():返回字符串的长度: return value.length
char charAt(int index): 返回某索引处的字符return value[index]
boolean isEmpty():判断是否是空字符串:return value.length == 0
String toLowerCase():使用默认语言环境,将 String 中的所有字符转换为小写
String toUpperCase():使用默认语言环境,将 String 中的所有字符转换为大写
String trim():返回字符串的副本,忽略前导空白和尾部空白
boolean equals(Object obj):比较字符串的内容是否相同
boolean equalsIgnoreCase(String anotherString):与equals方法类似,忽略大小写
String concat(String str):将指定字符串连接到此字符串的结尾。 等价于用“+”
int compareTo(String anotherString):比较两个字符串的大小,涉及到字符串排序,
返回负数就当前对象小,0就相等(字符串中每一个char型转Unicode编码来算)
String substring(int beginIndex):返回一个新的字符串,它是此字符串的从beginIndex开始截取到最后的一个子字符串。
String substring(int beginIndex, int endIndex) :返回一个新字符串,
它是此字符串从beginIndex开始截取到endIndex(不包含)的一个子字符串。
boolean endsWith(String suffix):测试此字符串是否以指定的后缀结束
boolean startsWith(String prefix):测试此字符串是否以指定的前缀开始
boolean startsWith(String prefix, int toffset):测试此字符串从指定索引开始的子字符串是否以指定前缀开始
boolean contains(CharSequence s):当此字符串包含指定的 char 值序列(字符串)时,返回 true
int indexOf(String str):返回指定子字符串在此字符串中第一次出现处的索引
int indexOf(String str, int fromIndex):从指定的索引开始找,返回指定子字符串在此字符串中第一次出现处的索引
int lastIndexOf(String str):返回指定子字符串在此字符串中最右边出现处的索引
int lastIndexOf(String str, int fromIndex):返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索
注:indexOf和lastIndexOf方法如果未找到都是返回-1
替换:
String replace(char oldChar, char newChar):返回一个新的字符串,它是通过用 newChar 替换此字符串中出现的所有 oldChar 得到的。
String replace(CharSequence target, CharSequence replacement):使用指定的字面值替换序列替换此字符串所有匹配字面值目标序列的子字符串。
String replaceAll(String regex, String replacement) : 使用给定的replacement 替换此字符串所有匹配给定的正则表达式的子字符串。
String replaceFirst(String regex, String replacement) : 使用给定的replacement 替换此字符串匹配给定的正则表达式的第一个子字符串。
匹配:
boolean matches(String regex):告知此字符串是否匹配给定的正则表达式。
切片:
String[] split(String regex):根据给定正则表达式的匹配拆分此字符串。
String[] split(String regex, int limit):根据匹配给定的正则表达式来拆分此字符串,最多不超过limit个,如果超过了,剩下的全部都放到最后一个元素中。
.
.
String类与其他结构之间的转换
String 与基本数据类型、包装类之间的转换。
String --> 基本数据类型、包装类:调用包装类的静态方法:parseXxx(str)
基本数据类型、包装类 --> String:调用String重载的valueOf(xxx)
String 与 char[] 之间的转换
String --> char[]:调用String的toCharArray()
char[] --> String:调用String的构造器
String 与 byte[] 之间的转换
编码:String --> byte[]:调用String的getBytes()
解码:byte[] --> String:
编码:字符串 --> 字节 (写的代码 --> 计算机的二进制数据)
解码:字节 --> 字符串 (计算机底层的二进制数据 --> 看得懂)
说明:解码时,要求解码使用的字符集必须与编码时使用的字符集一致,否则乱码
.
.
关于StringBuffer和StringBuilder的使用
String、StringBuilder 转换 String:调用toString()即可!
String、StringBuffer、StringBuilder三者异同?
String:底层使用char[]数组进行存储,是不可变的字符序列;
StringBuffer:底层使用char[]数组进行存储,是可变的字符序列; 线程安全的,效率低;
StringBuilder:底层使用char[]数组进行存储,是可变的字符序列; jdk5.0新增,线程不安全,效率高;
StringBuffer、StringBuilder 对字符串内容进行增删,此时不会产生新的对象。
源码分析:
String:
String str = new String();//底层:char[] value = new char[0];
String str1 = new String("abc");//底层:char[] value = new char[]{'a','b','c'};
StringBuffer 和 StringBuilder:两种在底层结构都一样,除了线程安全问题~
StringBuffer sb = new StringBuffer();//底层:char[] value = new char[16];
sb.append('a');//value[0] = 'a';
sb.append('b');//value[1] = 'b';
StringBuffer sb1 = new StringBuffer("abc");//底层:char[] value = new char["abc".length() + 16];
问题1:System.out.println(sb1.length());//3
问题2:扩容问题,如果添加的数据超出底层的数组,那就需要扩容数组。
默认情况下,扩容为原来容量的2倍 + 2,同时将原有数组中的元素复制到新的数组中。
源码查看append()方法;
开发中建议使用:StringBuffer(int capacity) 或 StringBuilder(int capacity)。手动设置cha[]的长度
对比String、StringBuilder、StringBuffer三者的效率:
StringBuilder > StringBuffer > String
说明:String、StringBuilder的效率远高于String,因为String是不可变的。
StringBuffer、StringBuilder的常用方法(两者一样)
StringBuffer append(xxx):提供了很多的append()方法,用于进行字符串拼接
StringBuffer delete(int start,int end):删除指定位置的内容
StringBuffer replace(int start, int end, String str):把[start,end)位置替换为str
StringBuffer insert(int offset, xxx):在指定位置插入xxx
StringBuffer reverse() :把当前字符序列逆转
public int indexOf(String str)
public String substring(int start,int end):返回一个从start开始到end索引结束(左闭右开)的子字符串。
public int length()
public char charAt(int n )
public void setCharAt(int n ,char ch)
总结:
增:append(xxx)
删:delete(int start,int end)
改:setCharAt(int n ,char ch)/replace(int start, int end, String str)
查:charAt(int n)
长度:length()
遍历:for() + charAt() / toString()
.
.
.
JDK8之前日期时间API
** System类中的currentTimeMillis():返回当前时间与1970年1月1日0时0分0秒之间以毫秒为单位的时间差**
.
.
.
Date类
java.util.Date类
1.两个构造器的使用
构造器一:Data();创建一个对应当前时间的Date对象
构造器二:new Date(163767251262L);创建指定毫秒数的对象
2.两个方法的使用
toString():显示当前的年、月、日、时、分、秒
getTime():返回自 1970 年 1 月 1 日 00:00:00 GMT 以来此 Date 对象表示的毫秒数。
java.sql.Date类
1.java.sql.Date对应着数据库中的日期类型的变量
如何实例化:new java.sql.Date(1536725543462L);返回参数(毫秒数)的:年-月-日
如何将java.util.Date对象转换java.sql.Date对象
Date date1 = new Date();
java.sql.Date date2 = new java.sql.Date(date1.getTime());
.
.
java.text.SimpleDateFormat类
作用:
Date类 ---> 字符串
字符串 ---> Date类
SimpleDateFormat的使用:对日期Date类的格式化和解析
一:两个操作
① 格式化:日期 ---> 字符串
format(date) 返回String类型
② 解析:字符串 ---> 日期
parse(str) 返回Date类型
二:SimpleDateFormat的实例化
空参,不建议使用:new SimpleDateFormat();
带参,建议使用(设置格式):new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
注意:解析时要求字符串必须符合SimpleDateFormat识别的格式(通过构造器参数设置格式),否则,抛异常。
常用构造器的参数表示:
年:yyyy 月:MM 日:dd
时:hh 分:mm 秒:ss
月的表示必须为大写,小写是表示分的!!!
.
.
java.util.Calendar日历类(抽象类)
Calendar类的对象是可变的!!!
一、Calendar实例化的方法:
① 创建其实现类对象: new GregorianCalendar
② 调用Calendar静态方法 getInstance()
Calendar calendar = Calendar.getInstance();
二、常用方法
① void get(int field):来取得想要的时间信息。
比如:YEAR、MONTH、DAY_OF_WEEK、HOUR_OF_DAY 、MINUTE、SECOND
格式:
int days = calendar.get(Calendar.DAY_OF_MONTH);//返回 int --> 这个月的第几天
② void set(int field,int value):修改当前时间信息为 value
格式:
calendar.set(Calendar.DAY_OF_MONTH,22);//修改这个月的第几天为22天
③ void add(int field,int amount):返回 当前的时间信息 加上 amount
格式:
calendar.add(Calendar.DAY_OF_MONTH,3);//在这个月的第几天的基础上加上3天
④ Date getTime():日历类 ---> Date类
格式:Date date = calendar.getTime();
⑤ void setTime(Date date):Date类 --> 日历类
格式:
Date date1 = new Date();
calendar.setTime(date1);
calendar.get(Calendar.DAY_OF_MONTH);//返回 date1 的时间信息
注意:
获取月份时:一月是0,二月是1,以此类推,12月是11
获取星期时:周日是1,周二是2 , 。。。。周六是7
.
.
.
JDK8中新日期时间API
介绍:
新的 java.time 中包含了所有关于本地日期(LocalDate)、本地时间(LocalTime)、本地日期时间(LocalDateTime)、时区(ZonedDateTime)和持续时间(Duration)
的类。
.
.
LocalDate、LocalTime、LocalDateTime 类是其中较重要的几个类,它们的实例是不可变的对象
.
.
LocalDate:代表IOS格式(yyyy-MM-dd)的日期,可以存储 生日、纪念日等日期。
LocalTime:表示一个时间,而不是日期。
LocalDateTime:是用来表示日期和时间的,这是一个最常用的类之一。
Date:日期(年、月、日)
Time:时间(时、分、秒)
类似与Calendar类
一、实例化
① now():实例化并获取当前的日期、时间、日期+时间
格式:
LocalDate localDate = LocalDate.now();
LocalTime localTime = LocalTime.now();
LocalDateTime localDateTime = LocalDateTime.now();
② of():实例化并设置指定的年、月、日、时、分、秒。没有偏移量
格式:LocalDateTime localDateTime1 = LocalDateTime.of(2021, 11, 25, 7, 10, 20);
二、常用方法
① getXxx():获取相关时间信息
格式:
localDateTime.getDayOfMonth(); // 获取这个月的第几天
localDateTime.getDayOfWeek(); // 获取这个星期的星期几
localDateTime.getMonth(); //获取今年的第几月 String值
localDate.getMonthValue(); //获取今年的第几月 int值
② withXxx():设置相关时间信息,并赋给新对象
格式:
LocalDate localDate1 = localDate.withDayOfMonth(22);
③ plusXxx(形参):在原有的时间信息基础上加上形参里的值,并赋给新对象
格式:
LocalDateTime localDateTime2 = localDateTime.plusMonths(3);
④ minusXxx(形参):在原有的时间信息基础上减去形参里的值,并赋给新对象
格式:
LocalDateTime localDateTime3 = localDateTime.minusYears(2);
withXxx()、plusXxx(形参)、minusXxx(形参) 这三个方法都体现了,LocalDate、LocalTime、LocalDateTime 类的不可变性!!!
.
.
Instant类(瞬时)
类似与 java.util.Date类
一、实例化
① now():获取Instant实例,并获取本初子午线(中时区)对应的标准时间
格式:
Instant instant = Instant.now();
② ofEpochMilli(long millis):通过给定的毫秒数,获取Instant实例 ---> Date(long millis)
格式:
Instant instant1 = Instant.ofEpochMilli(1637764732953L);
二、方法
① atOffset(ZoneOffset offset):添加时间的偏移量
格式:
OffsetDateTime offsetDateTime = instant.atOffset(ZoneOffset.ofHours(8));
② toEpochMilli():获取对应毫秒数(自1970年1月1日0时0分0秒(UTC)开始的毫秒数)
格式:
long milli = instant.toEpochMilli();
.
.
java.time.format.DateTimeFormatter 类
类似于:SimpleDateFormat
实例化:
方式一:预定义的标准格式 如:ISO_LOCAL_DATE_TIME;ISO_LOCAL_DATE;ISO_LOCAL_TIME
DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
方式二:本地化相关的格式 如:ofLocalizedDateTime()
DateTimeFormatter formatter1 = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL);
方式三:自定义的格式。如:ofPattern("yyyy-MM-dd hh:mm:ss")
DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
方法:
格式化:日期 --> 字符串
LocalDateTime localDateTime = LocalDateTime.now();
String s1 = formatter.format(localDateTime);
System.out.println(s1);
解析:字符串 --> 日期
TemporalAccessor parse = formatter.parse(s1);
System.out.println(parse);
.
.
其他日期时间API
.
.
对象的比较:Comparable接口 的 与Comparator接口
说明:Java中的对象,正常情况下,只能进行比较:== 或 != ,不能使用 > 或 < 的。
但是在开发场景中,我们需要对多个对象进行排序,言外之意,就需要比较对象的大小。
.
.
Comparable接口的使用举例: 自然排序
1.像String、包装类等实现了Comparable接口,重写了compareTo(obj)方法,给出了比较两个对象大小的方式。
2.像String、包装类重写compareTo()方法以后,进行了从小到大排序
3.重写compareTo()的规则:
如果当前对象this大于形参对象obj,则返回正整数,
如果当前对象this小于形参对象obj,则返回负整数,
如果当前对象this等于形参对象obj,则返回零。
4.对于自定义类来说,如果需要排序,我们可以让自定义类实现Comparable接口,重写compareTo(obj)方法。
在compareTo(obj)方法中指明如何排序。(和重写equals()方法差不多)
.
.
Comparator接口的使用:定制排序
1.背景:
当元素的类型没有实现java.lang.Comparable接口而又不方便修改代码,
或者实现了java.lang.Comparable接口的排序规则不适合当前的操作,那
么可以考虑使用 Comparator 的对象来排序
2. 重写compare(Object o1,Object o2)方法,比较o1和o2的大小:
如果方法返回正整数,则表示o1大于o2;
返回负整数,表示o1小于o2;
如果返回0,表示相等。
.
.
Comparable接口的与Comparator接口的对比:
Comparable接口的方式一旦指定,保证Comparable接口实现类的对象在任何位置都可以比较大小。
Comparator接口属于临时性的比较,什么时候需要就临时创建一个Comparator接口的实现类比较一下就可以。
.
.
.
System类
System类代表系统,系统级的很多属性和控制方法都放置在该类的内部。该类位于java.lang包。
工具类:
由于该类的构造器是private的,所以无法创建该类的对象,也就是无法实例化该类。
其内部的成员变量和成员方法都是static的,所以也可以很方便的进行调用。
.
.
成员变量
System类内部包含in、out和err三个成员变量,分别代表标准输入流(键盘输入),标准输出流(显示器)和标准错误输出流(显示器)。
.
.
成员方法
currentTimeMillis() 返回1970年1月1号0时0分0秒所差的毫秒数
exit(int status) 该方法的作用是退出程序。其中status的值为0代表正常退出,非零代表异常退出。使用该方法可以在图形界面编程中实现程序的退出功能
gc() 该方法的作用是请求系统进行垃圾回收
getProperty(String key) 该方法的作用是获得系统中属性名为key的属性对应的值
系统中常见的属性名以及属性的作用如下表所示:
.
.
.
Math类
java.lang.Math提供了一系列静态方法用于科学计算。其方法的参数和返回值类型一般为double型。
abs 绝对值
acos,asin,atan,cos,sin,tan 三角函数
sqrt 平方根
pow(double a,doble b) a的b次幂
log 自然对数
exp e为底指数
max(double a,double b)
min(double a,double b)
random() 返回0.0到1.0的随机数
long round(double a) double型数据a转换为long型(四舍五入)
toDegrees(double angrad) 弧度—>角度
toRadians(double angdeg) 角度—>弧度
.
.
.
BigInteger类
背景
Integer类作为int的包装类,能存储的最大整型值为231-1,Long类也是有限的,最大为263-1。
如果要表示再大的整数,不管是基本数据类型还是他们的包装类都无能为力,更不用说进行运算了
java.math包的BigInteger可以表示不可变的任意精度的整数。
BigInteger 提供所有 Java 的基本整数操作符的对应物,并提供 java.lang.Math 的所有相关方法。
另外,BigInteger 还提供以下运算:模算术、GCD 计算、质数测试、素数生成、位操作以及一些其他操作。
构造器:
BigInteger(String val):根据字符串构建BigInteger对象
常用方法:
public BigInteger abs():返回此 BigInteger 的绝对值的 BigInteger。
BigInteger add(BigInteger val) :返回其值为 (this + val) 的 BigInteger
BigInteger subtract(BigInteger val) :返回其值为 (this - val) 的 BigInteger
BigInteger multiply(BigInteger val) :返回其值为 (this * val) 的 BigInteger
BigInteger divide(BigInteger val) :返回其值为 (this / val) 的 BigInteger。整数相除只保留整数部分。
BigInteger remainder(BigInteger val) :返回其值为 (this % val) 的 BigInteger。
BigInteger[] divideAndRemainder(BigInteger val):返回包含 (this / val) 后跟(this % val) 的两个 BigInteger 的数组。
BigInteger pow(int exponent) :返回其值为 (thisexponent) 的 BigInteger。
.
.
.
BigDecimal类
背景
一般的Float类和Double类可以用来做科学计算或工程计算,但在商业计算中,要求数字精度比较高,故用到java.math.BigDecimal类。
BigDecimal类支持不可变的、任意精度的有符号十进制定点数。
构造器:
public BigDecimal(double val)
public BigDecimal(String val)
常用方法:
public BigDecimal add(BigDecimal augend)
public BigDecimal subtract(BigDecimal subtrahend)
public BigDecimal multiply(BigDecimal multiplicand)
public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode)
.
.
.
枚举类
类的对象只有有限个,确定的
。
举例如下:
星期类定义的对象:Monday(星期一)、......、Sunday(星期天)
性别类定义的对象:Man(男)、Woman(女)
季节类定义的对象:Spring(春节)......Winter(冬天)
支付类方式定义的对象:Cash(现金)、WeChatPay(微信)、Alipay(支付宝)、BankCard(银
行卡)、CreditCard(信用卡)
就职状态类定义的对象:Busy、Free、Vocation、Dimission
订单状态类定义的对象:Nonpayment(未付款)、Paid(已付款)、Delivered(已发货)、
Return(退货)、Checked(已确认)Fulfilled(已配货)、
线程状态类定义的对象:创建、就绪、运行、阻塞、死亡
当需要定义一组(相互之间有关系,例如以上举例星期类、性别类...)对象时,强烈建议使用枚举类!!!
如果枚举类中只有一个对象,则可以作为单例模式的实现方式。
.
.
定义枚举类
方式一:jdk5.0之前,自定义枚举类
1. 私有化类的构造器,保证不能在类的外部创建其对象(满足:有限个,确定的)
2. 在类的内部创建枚举类的实例对象。声明为:public static final
3. 对象如果有实例变量,应该声明为private final,并在构造器中初始化
4. 若还有其他需求(如:get()、toString()..),均写在类中
.
.
方式二:jdk5.0,可以使用enum关键字定义枚举类
使用 enum 定义的枚举类默认继承了 java.lang.Enum类,因此不能再继承其他类
必须在枚举类的第一行声明枚举类对象
枚举类的所有实例对象必须在枚举类中显式列出(以 "," 分隔 " ; " 结尾)。列出的实例对象系统会自动添加 public static final 修饰
枚举类的构造器只能使用 private 权限修饰符
1. 提供枚举类的对象,多个对象之间用","隔开,末尾对象";"结束
格式:
对象名1(形参列表),
对象名2(形参列表),
对象名3(形参列表);
2. 对象如果有属性则声明枚举类的属性:private final修饰
3. 私有化类的构造器,并给对象属性赋值
4. 若还有其他需求(如:get()、toString()..),均写在类中
.
.
Enum类中的常用方法
values()方法:返回枚举类型的对象数组。该方法可以遍历所有的枚举值。
valueOf(String str):返回枚举类中对象名是 str 的对象。如不是,会有运行时异常:IllegalArgumentException。
toString():返回当前枚举类对象常量的名称
.
.
使用enum关键字定义枚举类实现接口的情况
情况一:若每个枚举类的对象在调用实现的接口方法呈现相同的行为方式,则只要统一实现该方法即可。
情况二:若需要每个枚举类的对象在调用实现的接口方法呈现出不同的行为方式, 则可以让每个枚举类的对象分别来实现该方法。
格式:
对象名1(形参列表){
//编写实现的接口方法
},
对象名2(形参列表){
//编写实现的接口方法
},
对象名3(形参列表){
//编写实现的接口方法
};
.
.
.
注解的使用
1.理解Annotation
① jdk 5.0 新增的功能
② Annotation 其实就是代码里的特殊标记, 这些标记可以在编译, 类加载, 运行时被读取, 并执行相应的处理。
通过使用 Annotation, 程序员可以在不改变原有逻辑的情况下, 在源文件中嵌入一些补充信息。
③ 在JavaSE中,注解的使用目的比较简单,例如标记过时的功能,忽略警告等。
在JavaEE/Android中注解占据了更重要的角色,例如用来配置应用程序的任何切面,
代替JavaEE旧版中所遗留的繁冗代码和XML配置等。
.
.
2. Annotation(注解)的使用示例
示例一:生成文档相关的注解
示例二:在编译时进行格式检查(JDK内置的三个基本注解)
@Override: 限定重写父类方法, 该注解只能用于方法
@Deprecated: 用于表示所修饰的元素(类, 方法,属性,构造器等)已过时。通常是因为所修饰的结构危险或存在更好的选择
@SuppressWarnings: 抑制编译器警告(定义一个变量或方法时使用,可表示还没有使用或没有使用泛型等等)
示例三:跟踪代码依赖性,实现替代配置文件功能
Servlet3.0提供了注解(annotation),使得不再需要在web.xml文件中进行Servlet的部署。
.
.
3. 如何自定义注解:参照@SuppressWarnings定义
① 注解声明为 @interface
② 内部定义成员变量,通常使用value表示 格式:String value()、String[] value()等等...
③ 可以指定成员的默认值,使用default定义 格式:String value() default "hello";
④ 如果自定义注解没有成员,表名是一个标识作用。
⑤ 如果注解有成员,在使用注解时,需要指明成员的值,若有默认值则不指明也可以。
关于注解支持的元素(内部定义成员变量)数据类型:
所有基本类型(int,float,boolean,byte,double,char,long,short)
String
Class
enum
Annotation
上述类型的数组
.
.
4. jdk 提供的4种元注解(元Annotation)
① 元数据的理解:
例如:String name = "atguigu";
解释:String和name就是元数据,"atguigu"就是数据。
② 和元数据一样,元注解:对现有的注解进行解释说明的注解。
格式:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
以上代码中@Target(ElementType.METHOD)和@Retention(RetentionPolicy.SOURCE)就是元注解,
是对 @Override注解进行解释说明。
JDK5.0提供了4个标准的meta-annotation类型(元注解),分别是:
Retention:指定所修饰的 Annotation(注解) 的生命周期。
生命周期包括:
RetentionPolicy.SOURCE:在源文件中有效(即源文件保留);
该类型的注解信息只会保留在源码里,源码经过编译后,注解信息会被丢弃,不会保留在编译好的class文件里。
RetentionPolicy.CLASS:这是默认值,在class文件中有效(即class保留;
该类型的注解信息会保留在源码里和class文件里,在执行的时候,不会加载到虚拟机中。
RetentionPolicy.RUNTIME:在运行时有效(即运行时保留);
当运行 Java 程序时, JVM 会保留注释,因此可以通过反射机制读取注解的信息(源码、class文件和执行的时候都有注解的信息)。
注意:只有声明为RUNTIME生命周期的注解,才能通过反射获取。
Target:指定所修饰的 Annotation 能用于修饰哪些程序元素。
请注意,当注解未指定Target值时,则此注解可以用于任何元素之上,多个值使用{}包含并用逗号隔开,如下:
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
以下两个元注解出现频率较低
Documented:表示所修饰的注解在被javadoc解析是,保留下来,默认情况下,javadoc是不包括注解的。
定义为Documented的注解必须设置Retention值为RUNTIME。
Inherited: 表示所修饰的 Annotation 将具有继承性。如果某个类使用了被@Inherited 修饰的 Annotation, 则其子类将自动具有该注解。
注意:自定义注解必须配上注解的信息处理流程(使用反射)才有意义。
自定义注解通常会指明两个元注解:Retention、Target。
.
.
6. jdk 8 中注解的新特性:可重复注解、类型注解
1. 可重复注解:
① 在MyAnnotation上声明@Repeatable,成员值为MyAnnotations.class
② 需要MyAnnotation的Target和Retention等元注解与MyAnnotations的相同
2. 类型注解:关于元注解@Target的参数类型ElementType枚举值多了两个:TYPE_PARAMETER,TYPE_USE。
ElementType.TYPE_PARAMETER 表示该注解能写在类型变量的声明语句中(如:泛型声明)。
ElementType.TYPE_USE 表示该注解能写在使用类型的任何语句中。