JDK8-Lang框架分析(二)

1简 介

    JAVA language,语言包,提供利用Java编程语言进行程序设计的基础类。包含Java语言所需要的基本功能类、接口等信息。将基本类型的值封装成对象包装器类(如 BooleanCharacterIntegerLongFloat Double等);注解;反映;MxBean;CompilerRuntime、进程Process、线程Thread;ClassClassLoaderPackageObject等。

2体系结构

2.1 Annotation注解(@interface)

背景:java中,注解作为程序的元数据嵌入到程序当中,元数据标签的存在并不影响程序代码的编译和执行。所谓Annotation就是提供了一种为程序元素设置元数据的方法,可用于修饰包、类、构造器、方法、成员变量、参数和局部变量(具体详见元注解 Target)的声明。注解可以被一些解析工具或者是编译工具进行解析。Annotation中的信息可以在编译、加载和运行时被读取(具体详见元注解 Retention),并执行相应的处理。当前许多java框架中大量使用注解,如HibernateJerseySpring.

   数据和元数据:数据是指普通文件中的实际数据,而元数据指用来描述一个文件的特征的系统数据,诸如访问权限、文件拥有者以及文件数据块的分布信息等等。在集群文件系统中,分布信息包括文件在磁盘上的位置以及磁盘在集群中的位置。用户需要操作一个文件必须首先得到它的元数据,才能定位到文件的位置并且得到文件的内容或相关属性

引入原因:1)可将方法声明为服务 2)定义了一种标准的描述元数据的方式

定义使用@interface可自定义注解,自动继承java.lang.annotation.Annotation接口不能继承其他的注解或接口

格式:public @interface 注解名 {定义体},成员变量遵守规则

    以无形参的方法形式来声明,其方法名和返回值定义了该成员变量的名字和返回类型

    使用带有属性的Annotation时,必须为其属性指定值或通过default关键字指定默认值。

    属性类型只能是基本类型String不允许IntegerDouble等)enumClass及上述类型的一维数组类型

JDK Annotation关系图:

5个元注解 meta-annotation

元注解的作用就是负责注解其他注解Java8定义5个标准的 meta-annotation 类型,即@Target@Retention@Repeatable@Documented@Inherited,它们被用来提供对其它 annotation 类型作说明(只能作用在注解上,不能作用在其他程序元素上)

Target 元素种类【重要】

@Documented

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.ANNOTATION_TYPE)

public @interface Target {

    ElementType[] value();

}

指示注解类型所适用的程序元素的种类,明晰其修饰的目标.

@Target用来限定一个Annotation可以用于修饰哪些程序元素(可修饰的程序元素由 ElementType 限定),由@Target(ElementType.ANNOTATION_TYPE)来限定表明此注解只能用在注解类型元素的声明上,如果无@interface Target,则在自定义@interface注解时必须在头部加上使用元注解@Target(value = { ElementType.TYPE, ElementType.METHOD, ElementType.LOCAL_VARIABLE, ElementType.FIELD })

ElementType定义:

1 TYPE:类、接口(包括注解类型) enum声明描述;

2 FIELD:属性描述;   3.METHOD:方法描述;   4.PARAMETER:参数描述;

5 CONSTRUCTOR:构造器描述;     6.LOCAL_VARIABLE:局部变量描述;

7 Annotation_Type:注解类型描述;   8 PACKAGE:包描述;

9 Type_Parameter:类型参数描述;   10 Type_Use:使用类型;

Retention 保留策略【重要】

@Documented

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.ANNOTATION_TYPE)

public @interface  Retention {

    RetentionPolicy value();

}

指示注解类型的注解要保留多久

@Retention(RetentionPolicy.RUNTIME)指定保留,如果注解类型声明中不存在 Retention 注解,则保留策略默认为 RetentionPolicy.CLASS

RetentionPolicy定义:

SOURCE:在源文件中有效(即源文件保留),编译compiler失效;

CLASS:class文件中有效(即class保留),默认保留策略,VM行失效;

RUNTIME:VM运行时有效(即运行时保留),支持通过反射获取注解信息

Documented 文档化

@Documented

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.ANNOTATION_TYPE)

public @interface  Documented {

}

指示某一类型的注释将通过 javadoc 和类似的默认工具进行文档化。

Inherited 自动继承

@Documented

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.ANNOTATION_TYPE)

public @interface Inherited {

}

指示注解类型被自动继承。

如果在注解类型声明中存在 Inherited 注解,并且用户在某一类声明中查询该注解类型,同时该类声明中没有此类型的注解,则将在该类的超类中自动查询该注解类型。此过程会重复进行,直到找到此类型的注解或到达了该类层次结构的顶层 (Object) 为止;如果没有超类具有该类型的注解,则查询将指示当前类没有这样的注解此元注解仅促成从超类继承注解,对已实现接口的注解无效

Repeatable重复注解JDK1.8新加)

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Repeatable {
    /**
     * Indicates the <em>containing annotation type</em> for the
     * repeatable annotation type.
     * @return the containing annotation type
     */
    Class<? extends Annotation> value();
}

允许在同一申明类型(类,属性,或方法)的多次使用同一个注解

以上5个元注解共性:定义包含@Target(ElementType.ANNOTATION_TYPE)

注解只能用在注解类型元素的声明上,ElementType 限定;@Retention(

RetentionPolicy.RUNTIME),即运行时 VM 保留注解

Native注解(JDK1.8新加)

@Documented

@Target(ElementType.FIELD)

@Retention(RetentionPolicy.SOURCE)

public @interface Native {}

仅仅用来标记native的属性

2.2反射Reflect

   在运行状态中,对于任意一个类,都能够知道此类的所有属性和方法;对于任意一个对象,都能够调用此对象的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法 的功能称为java语言反射Reflection机制,使的Java具体了动态性

基本概念

正常情况下,如要使用类,则必须按照如下的步骤操作:

1)使用import导入类所在的包(java.lang.Class)

2)明确的使用类名称或接口名称定义对象。

3) 通过关键字new进行类对象实例化(构造方法:reflect.Constructor)

4) 产生对象可使用对象.属性”进行类属性的调用(属性reflect.Field)

反射过程不需要明确类型的对象,所有的对象使用Object表示,类关系图:

AnnotatedElement:注解元素操作类。表示运行在当前VM中的程序注解元素,这个接口允许对注解进行反射,该接口中方法返回的所有注释都是不可变的和可序列化的。这个接口的方法返回的数组可能会被调用者修改,而不会影响到返回给其他调用者的数组。
Member:提供类和接口,以获取关于类和对象的反射信息。
GenericDeclaration:声明类型变量的所有实体的公共接口
AccessibleObjectField,Contrutor,Method类的基本类,用于控制可访问.

Filed:类中的属性
ExecutableConstructor,Method共享通用功能的超类
Contrutor:类中的构造器  Method:类中的方法  Annotation:类中的注解

Object:对象类,类层次结构的根   Type:返回这个类的名称(e.g. java.lang.Class)  ClassClass代表类的实例(类类型)

Class-实例化对象

涉及方法:

@CallerSensitive

public T newInstance(){...}//调用类默认无参构造函数实例化类对象

@CallerSensitive

public Constructor<?>[] getConstructors(){...}//取得类之中的全部构造

public Constructor<T> getConstructor(Class<?>... parameterTypes){...}//取得类之中指定参数的构造

package lang.reflect;
public class Person {
	private String name = "CJ";
	public Person() {
		System.out.print("Peson类的无参构造方法,name="+name +"...");
	}
	public Person(String name) {
		this.name = name;
		System.out.print("Peson类的带参构造方法,name="+this.name+"...");
	}
	@Override
	public String toString() {
		return "Peson类的toString()方法...";
	}
	public String getName() {
		System.out.println("Peson getName="+this.name+"...");
		return name;
	}

	public void setName(String name) {
		this.name = name;
                System.out.print("Peson setName="+this.name+"...");		
	}

        public static void main(String[] args) throws Exception {
	        System.out.println("*1 Class newInstance(),调用类默认无参构造函数 实例化类对象*");
		Class<?> defalutClazz = Class.forName("lang.reflect.Person");
		Object defalutObj = defalutClazz.newInstance();
		System.out.println(defalutObj);
		System.out.println("*2 Constructor newInstance(参数值),调用类带参构造函数实例化类对象*");
		Class<?> clazz = Class.forName("lang.reflect.Person");
		Constructor<?> constu = clazz.getConstructor(String.class);
		//Constructor<?> cons[] = clazz.getConstructors();//or get all constructors
		Object constuObj = constu.newInstance("CJ-Constructor");
		System.out.println(constuObj);
	}
}

Output:*1 Class newInstance(),调用类默认无参构造函数 实例化类对象*

Peson类的无参构造方法,name=CJ...Peson类的toString()方法...

*2 Constructor newInstance(参数值),调用类带参构造函数实例化类对象*

Peson类的带参构造方法,name=CJ-Constructor...Peson类的toString()方法...

Constructor-操作构造方法

@CallerSensitive

public T newInstance(Object ... initargs){...}//调用类带参构造函数实例化类对象

Class-调用方法Method

涉及方法:

1)取得父类继承而来的方法和本类方法:
取得全部方法 Methods[] getMethods();
取得指定方法 Methods getMethod(String name, Class<?>… parameterType)
  2)取得本类定义的方法
取得全部方法 Method[] getDeclaredMethods()
取得指定方法 Method getDeclaredMethod(String name,Class<?>… parameterType)

Person类启动方法加入代码:

System.out.println("*3 Method 反射调用类中的方法*");

Method msetNameMethod = defalutObj.getClass().getDeclaredMethod("setName",String.class);

msetNameMethod.invoke(defalutObj,"CJ-setName");

Method mgetNameMethod = defalutObj.getClass().getDeclaredMethod("getName", new Class<?>[0]);

mgetNameMethod.invoke(defalutObj);

Output: *3 Method 反射调用类中的方法*

Peson setName=CJ-setName...Peson getName=CJ-setName...

Class–调用类中的属性Field(尽量不要去使用)

关于类中的属性也可以直接利用反射进行操作,而支持的方法有两类:
1)取得所有继承而来的属性
取得全部属性 public Field[] getFields()
取得指定属性 public Field getField(String name)
2)取得本类定义的属性
取得本类全部属性public Field getDeclareFields()
取得本类全部属性public Field getDeclareField(String name)

Method-反射调用类中的方法

涉及方法:

public Object invoke(Object obj, Object… args)

Person类启动方法加入代码:

System.out.println("*3 Method 反射调用类中的方法*");

Method _setName = clazz.getMethod("setName",String.class);

_setName.invoke(defalutObj, "CJ-setName");

Method getNameMethod = clazz.getMethod("getName");

getNameMethod.invoke(defalutObj);

Output: *3 Method 反射调用类中的方法*

Peson setName=CJ-setName...Peson getName=CJ-setName...

Method-常用方法

1)取得方法的返回类型:public Class<?> getReturnType();
2)取得方法的参数:public Class<?> getParameterTypes();
3)取得所有抛出的异常:public Class<?> getExceptionTypes();

Field-设置/获取属性内容

1)设置属性内容:public void set(Object obj, Object value)
2)取得属性内容:public Object get(Object obj);

Person类启动方法加入代码:

       System.out.println("*4 Field类-设置/获取属性内容*");

       Field nameField = clazz.getDeclaredField("name");

        nameField.setAccessible(true);//必须设置可访问

        nameField.set(defalutObj, "CJ-Field");

        System.out.print(nameField.get(defalutObj));

Output:*4 Field类-设置/获取属性内容*

             CJ-Field

:1)Constructor、Method、Field三个类上有一个共同的父类 AccessibleOblect,在这个类中定义了可以取消封装操作:public void setAccessible(boolean flag)

   2)参数官网:https://www.programcreek.com/2013/09/java-reflection-tutorial/

2.3基础数据类型

关系图:

 public abstract class Number:

                                                          

4个抽象方法被子类实现,byteValue(),shortValue()java.mathBigInteger类调用。


猜你喜欢

转载自blog.csdn.net/jun55xiu/article/details/79363785