框架的底层实现机制。
1.注释给人看,注解给人和机器看 JDK5引进
1.什么是注解
- Annotation是从JDK5.0开始引入的新技术.
- Annotation的作用: 不是程序本身,可以对程序作出解释.(这一点和注释(comment)没什么区别)可以被其他程序(比如:编译器等)读取.
- Annotation的格式:
- 注解是以"@注释名"在代码中存在的,还可以添加一些参数值,例如:@SuppressWarnings(value="unchecked"").
- Annotation在哪里使用?
- 可以附加在package , class , method , field等上面﹐相当于给他们添加了额外的辅助信息,
更正:从JAVA8开始,注解几乎可以使用在任何元素上,局部变量、接口类型、超类和接口实现类,甚至可以用在函数的异常定义上。
1 / /什么是注解 2 public class Teste1 extends object { 3 / / @override ,重写的注解 4 @Override 5 public string tostring( { 6 Thread_ 7 return super.toStringl(); 8 }
2.常见的三个内置注解
内置注解
- @Override :定义在java.lang.Override中,此注释只适用于修辞方法﹐表示一个方法声明打算重写超类中的另一个方法声明.
- @Deprecated :定义在java.lang.Deprecated中,此注释可以用于修辞方法﹐属性,类,表示不鼓励程序员使用这样的元素﹐通常是因为它很危险或者存在更好的选择.
- @suppressWarnings:定义在java.lang.SuppressWarnings中,用来抑制编译时的警告信息.
与前两个注释有所不同,你需要添加一个参数才能正确使用,这些参数都是已经定义好 了的,我们选择性的使用就好了,
- @SuppressWarnings("all)
- @SuppressWarnings("unchecked")
- @SuppressWarnings(value=(""unchecked","deprecation""))
- 等等.........
1 //什么是注解 2 public class Test01 extends object { 3 //@override重写的注解 4 @Override 5 public string toString() { 6 return super.tostring() ; 7 / /@Deprecated不推若程序员使用,但是可以使用。或者存在更好的方式 8 9 @Deprecated 10 pubilic static void test(){ 11 System .out. println (""Deprecated") ; 12 13 } 14 15 public static void main(string[] args){ 16 test(); 17 18 }
@SuppressWarnings() 需要参数
如@SuppressWarnings("all")
镇压警告,不止可以放在方法上,也可以在类、字段、构造器等
JAVA8: @Functionallnterface 标明该接口是一个函数式接口
3.元注解
- 元注解的作用就是负责注解其他注解,Java定义了4个标准的meta-annotation类型,他们被用来提供对其他annotation类型作说明.
- Document:说明该注解将被包含在javadoc中
- @Inherited:说明子类可以继承父类中的该注解
@Target: 描述注解的适用范围, 如类、字段、方法等
ElementType:枚举类型
如定义用在方法上的注解:
@Target(Value=ElementType.METHOD)
用在类上就会报错:
1 1 import java.lang. annotation.ElementType ; 2 2 3 3 import java.lang. annotation.Target; 4 4 //测试元注解 5 5 public class Test02 { 6 6 @MyAnnotation 7 7 public void test() { 8 8 } 9 9 } 10 10 //定义一个注解 11 11 @Target(value = {ElementType.AETHOD,ElementType.TYPE}) 12 12 13 13 @interface MyAnnotation{ 14 14 }
@Retention: 表示我们的注解在什么地方还有效,用于描述注解生命周期
(SOURCE<CLASS<RUNTIME)
@Override: SOURCE
@Deprecated:RUNTIME
@SupressWarnings:SOURCE (只用于在源码上镇压警告的提示,编译后就不起作用了)
一般自定义注解都用RUNTIME
运行时: @Retention(RetentionPolicy.RUNTIME)
@Documented 是否将注解生成在JAVAdoc中
@Inherited子类可以继承父类的注解
//测试元注解 @MyAnnotation public class Test02 { public void test(){} } } //定义一个注解 / / Target表示我们的注解可以用在要些地方﹒ @Target(value = (ElementType.METHOD ,ElementType.TYPE}) // Retention表示我们的注解在什么地方还有效。 //runtime>class>sources @Retention (value = RetentionPolicy .RUNTIME) //Documented表示是否将我们的注解生成在JAVAdoc 中 @Documented //Inherited 子类可以继承父类的注解 @Inherited @interface MyAnnotation{ }
Java 8 : 使用 @Repeatable 注解定义重复注解。
4.自定义注解 @interface
使用@interface自定义注解时﹐自动继承了java.lang.annotation.Annotation接口 分析:
-
@interface用来声明一个注解﹐格式︰public @interface注解名{定义内容}√其中的每一个方法实际上是声明了一个配置参数.
-
方法的名称就是参数的名称.
-
返回值类型就是参数的类型(返回值只能是基本类型,Class , String , enum ).√可以通过default来声明参数的默认值
-
如果只有一个参数成员﹐一般参数名为value
-
import java.lang. annotation.ElementType; import java.lang. annotation .Retention; import java.lang- annotation.RetentionPolicy; import java.lang.annotation.Target; //自定义注解 public class Teste3 { //注解可以显示赋值,如果没有默认值,我们就必须给注解赋值 ? @MyAnnotation2( age = 18 ,name ="秦疆"") ? public void test(){} @Target(lElementType.TyPE,ElementType.wETHOD}) @Retention (RetentionPolicy .RUNTINE) @interface MyAnnotation2{ //注解的多数:参数类型+参数名(); ? String name() default ""; int age(); ? int id()default -1; ? //如果默认值为-1,代表不存在﹒ ? String[] schools() default{"西部开源"","清华大学"}; }
直接只有一个参数可以用value命名,传参时可以省略参数名(Target和Retention也是这样)
- @Target({ElementType.TYPE,ElementType.NETHOD}) @Retention (RetentionPolicy -RUNTINE) @interface MyAnnotation3{ String value(); }
5.反射
JAVA为静态语言,通过反射使其具有动态性
Java Reflection (反射)原理:允许程序在执行期间操作对象
Java反射机制提供的功能
- 在运行时判断任意一个对象所属的类
- 在运行时构造任意一个类的对象
- 在运行时判断任意一个类所具有的成员变量和方法
- 在运行时获取泛型信息
- 在运行时调用任意一个对象的成员变量和方法在
- 运行时处理注解
- 生成动态代理
- .....
Java反射优点和缺点
优点:
可以实现动态创建对象和编译,体现出很大的灵活性
缺点:
对性能有影响。使用反射基本上是一种解释操作,我们可以告诉JVM,我们希望做什么并且它满足我们的要求。这类操作总是慢于直接执行相同的操作。
Class.forName
一个类在内存中只有一个Class对象
//什么叫反射 public class Test02 { public static void main(String[] args) throws classNotFoundException { //通过反射获收类的class对象 Class c1 = Class.forName (""com. kuang.reflection.User""); ? System.out.println(c1); ? class c2 = class.forName ( ""com.kuang-reflection.User"); ? class c3 = class.forName (""com.kuang.reflection.User""); ? class c4 = class.forMName ("com.kuang.reflection.User"); //一个类在内存中只有一个class对象 //一个类被加载后,类的整个结构都会封装在class对象中。 ? System.out. println(c2.hashCode() ) ; ? System.out. println(c3.hashCode()); ? System.out. println(c4.hashCde()) ; ? } } ? //实体类: pojo , entity class user(...)
Class类
在Object类中定义了以下的方法,此方法将被所有子类继承
方法名 | 功能说明 |
static glassforName(String name) | 返回指定类名namegClass对象 |
Object newlnstance() | 调用缺省构造函数,返回Class对象的一个实例 |
getName() | 返回此Class对象所表示的实体(类,接口,数组类或void)的名称。 |
Class getSuperClass() | 返回当前Class对象的父类的Class对象 |
Class[] getinterfaces() | 获取当前Class对象的接口 |
ClassLoader getClassLoader() | 返回该类的类加载器 |
Constructor[getConstructors() | 返回一个包含某些Constructor对象的数组 |
Method getMothed(String name,Class.. T) | |
Field[]getDeclaredFields() | 返回Field对象的一个数组 |
public static void main(String[] args) throws classNotFoundException { Person person = new student( ); System.out. println("这个人是:"+person.name ) ; //方式一:通过对象获得 class ci = person.getclass (; System.ourt.println(c1.hashCode( ) ) ; //方式二 : forname获寻 class c2 = class.forName (""com.kuang.reflection.student"); ? system.out.println(c2.hashCode() ) ; ? //方式三:通过类名.class获得 ? class c3 = Student.class; ? System.out.println(e3.hashcode() ) ; ? //方式四:基本内置类型的包装类都有一个Type属性 ? class c4 = Integer.TYPE; ? system.out.println(c4); ? 获得父类类型 ? class e5 = c1-getSuperelass《);System.out- println(e5) ; } } class Person(---)
哪些类型可以有Class对象?
class:外部类,成员(成员内部类,静态内部类),局部内部类,匿名内部类,
interface:接口 []:数组
enum:枚举 annotation:注解@interface
primitive type:基本数据类型、
import java.lang.annotation.ElementType; //所有类型的class public class Test04 { public static void main(string[] args) { class ci = object.class; //类 class c2 - comparable.ciass;//接口 class c3 = string[].class;//一维数组 class c4 = int[] [].[][]class; //二维数组 Class c5 = Override.class; //注解 Class c6 = ElementType.class; //枚举 class c7 = Integer.class; //基本数据类型 class c8 = void.class; //void class cs - class.class; / /class System.out. println(c1) ; System.out. println(c2); system.out. println(c3) ; system.out.println(c4) ; System.out.println(e5) ; System.out. println(c6) ; system.out.println(c7) ; system.out.println(c8) ; System.out.println(c9) ; //只要元素类型与维度一样,就是同一个class. ? int[]a = new int[10] ; ? int[ ]b = new int[100] ; ? System.out.println(a-getclass( ).hashCode( ); ? System.out.println(b-getclass( ).hashCode(); ? } }
。
初始化: Java 类第一次被真正使用到的时候,JVM 会进行该类的初始化操作。从上到下的顺序依次执行静态代码块和初始化静态域。