摘要

Java Annotation是JDK5.0引入的一种注释机制。

网上很多关于Java Annotation的文章,看得人眼花缭乱。Java Annotation本来很简单的,结果说的人没说清楚;弄的看的人更加迷糊。

我按照自己的思路,对Annotation进行了整理。理解 Annotation 的关键,是理解Annotation的语法和用法,对这些内容,我都进行了详细说明;理解Annotation的语法和用法之后,再看Annotation的框架图,可能有更深刻体会。废话就说这么多,下面开始对Annotation进行说明。若您发现文章中存在错误或不足的地方,希望您能指出!

第1部分 Annotation架构

先看看Annotation的架构图:

从中,我们可以看出:

(01) 1个Annotation 和 1个RetentionPolicy关联。

可以理解为:每1个Annotation对象,都会有唯一的RetentionPolicy属性。

(02) 1个Annotation 和 1~n个ElementType关联。

可以理解为:对于每1个Annotation对象,可以有若干个ElementType属性。

(03) Annotation 有许多实现类,包括:Deprecated, Documented, Inherited, Override等等。

Annotation 的每一个实现类,都“和1个RetentionPolicy关联”并且“和1~n个ElementType关联”。

下面,我先介绍框架图的左半边(如下图),即Annotation, RetentionPolicy, ElementType;然后在就Annotation的实现类进行举例说明。

第2部分 Annotation组成部分

1 annotation组成成分

java annotation 的组成中,有3个非常重要的主干类。它们分别是:

(01) Annotation.java

packagejava.lang.annotation;public interfaceAnnotation {booleanequals(Object obj);inthashCode();

String toString();

Class extends Annotation>annotationType();

}

(02) ElementType.java

packagejava.lang.annotation;public enumElementType {

TYPE,/*类、接口(包括注释类型)或枚举声明*/FIELD,/*字段声明(包括枚举常量)*/METHOD,/*方法声明*/PARAMETER,/*参数声明*/CONSTRUCTOR,/*构造方法声明*/LOCAL_VARIABLE,/*局部变量声明*/ANNOTATION_TYPE,/*注释类型声明*/PACKAGE/*包声明*/}

(03) RetentionPolicy.java

packagejava.lang.annotation;public enumRetentionPolicy {

SOURCE,/*Annotation信息仅存在于编译器处理期间,编译器处理完之后就没有该Annotation信息了*/CLASS,/*编译器将Annotation存储于类对应的.class文件中。默认行为*/RUNTIME/*编译器将Annotation存储于class文件中,并且可由JVM读入*/}

说明:

(01) Annotation 就是个接口。

“每1个Annotation” 都与 “1个RetentionPolicy”关联,并且与 “1~n个ElementType”关联。可以通俗的理解为:每1个Annotation对象,都会有唯一的RetentionPolicy属性;至于ElementType属性,则有1~n个。

(02) ElementType 是Enum枚举类型,它用来指定Annotation的类型。

“每1个Annotation” 都与 “1~n个ElementType”关联。当Annotation与某个ElementType关联时,就意味着:Annotation有了某种用途。

例如,若一个Annotation对象是METHOD类型,则该Annotation只能用来修饰方法。

(03) RetentionPolicy 是Enum枚举类型,它用来指定Annotation的策略。通俗点说,就是不同RetentionPolicy类型的Annotation的作用域不同。

“每1个Annotation” 都与 “1个RetentionPolicy”关联。

a) 若Annotation的类型为 SOURCE,则意味着:Annotation仅存在于编译器处理期间,编译器处理完之后,该Annotation就没用了。

例如,“ @Override ”标志就是一个Annotation。当它修饰一个方法的时候,就意味着该方法覆盖父类的方法;并且在编译期间会进行语法检查!编译器处理完后,“@Override”就没有任何作用了。

b) 若Annotation的类型为 CLASS,则意味着:编译器将Annotation存储于类对应的.class文件中,它是Annotation的默认行为。

c) 若Annotation的类型为 RUNTIME,则意味着:编译器将Annotation存储于class文件中,并且可由JVM读入。

这时,只需要记住“每1个Annotation” 都与 “1个RetentionPolicy”关联,并且与 “1~n个ElementType”关联。学完后面的内容之后,再回头看这些内容,会更容易理解。

第3部分 java自带的Annotation

理解了上面的3个类的作用之后,我们接下来可以讲解Annotation实现类的语法定义了。

1 Annotation通用定义

@Documented

@Target(ElementType.TYPE)

@Retention(RetentionPolicy.RUNTIME)public @interfaceMyAnnotation1 {

}

说明:

上面的作用是定义一个Annotation,它的名字是MyAnnotation1。定义了MyAnnotation1之后,我们可以在代码中通过“@MyAnnotation1”来使用它。

其它的,@Documented, @Target, @Retention, @interface都是来修饰MyAnnotation1的。下面分别说说它们的含义:

(01) @interface

使用@interface定义注解时,意味着它实现了java.lang.annotation.Annotation接口,即该注解就是一个Annotation。

定义Annotation时,@interface是必须的。

注意:它和我们通常的implemented实现接口的方法不同。Annotation接口的实现细节都由编译器完成。通过@interface定义注解后,该注解不能继承其他的注解或接口。

(02) @Documented

类和方法的Annotation在缺省情况下是不出现在javadoc中的。如果使用@Documented修饰该Annotation,则表示它可以出现在javadoc中。

定义Annotation时,@Documented可有可无;若没有定义,则Annotation不会出现在javadoc中。

(03) @Target(ElementType.TYPE)

前面我们说过,ElementType 是Annotation的类型属性。而@Target的作用,就是来指定Annotation的类型属性。

@Target(ElementType.TYPE) 的意思就是指定该Annotation的类型是ElementType.TYPE。这就意味着,MyAnnotation1是来修饰“类、接口(包括注释类型)或枚举声明”的注解。

定义Annotation时,@Target可有可无。若有@Target,则该Annotation只能用于它所指定的地方;若没有@Target,则该Annotation可以用于任何地方。

(04) @Retention(RetentionPolicy.RUNTIME)

前面我们说过,RetentionPolicy 是Annotation的策略属性,而@Retention的作用,就是指定Annotation的策略属性。

@Retention(RetentionPolicy.RUNTIME) 的意思就是指定该Annotation的策略是RetentionPolicy.RUNTIME。这就意味着,编译器会将该Annotation信息保留在.class文件中,并且能被虚拟机读取。

定义Annotation时,@Retention可有可无。若没有@Retention,则默认是RetentionPolicy.CLASS。

2 java自带的Annotation

通过上面的示例,我们能理解:@interface用来声明Annotation,@Documented用来表示该Annotation是否会出现在javadoc中, @Target用来指定Annotation的类型,@Retention用来指定Annotation的策略。

理解这一点之后,我们就很容易理解java中自带的Annotation的实现类,即Annotation架构图的右半边。如下图:

java 常用的Annotation:

@Deprecated -- @Deprecated 所标注内容,不再被建议使用。

@Override-- @Override 只能标注方法,表示该方法覆盖父类中的方法。

@Documented-- @Documented 所标注内容,可以出现在javadoc中。

@Inherited-- @Inherited只能被用来标注“Annotation类型”,它所标注的Annotation具有继承性。

@Retention-- @Retention只能被用来标注“Annotation类型”,而且它被用来指定Annotation的RetentionPolicy属性。

@Target-- @Target只能被用来标注“Annotation类型”,而且它被用来指定Annotation的ElementType属性。

@SuppressWarnings-- @SuppressWarnings 所标注内容产生的警告,编译器会对这些警告保持静默。

由于“@Deprecated和@Override”类似,“@Documented, @Inherited, @Retention, @Target”类似;下面,我们只对@Deprecated, @Inherited, @SuppressWarnings 这3个Annotation进行说明。

2.1 @Deprecated

@Deprecated 的定义如下:

@Documented

@Retention(RetentionPolicy.RUNTIME)public @interfaceDeprecated {

}

说明:

(01) @interface -- 它的用来修饰Deprecated,意味着Deprecated实现了java.lang.annotation.Annotation接口;即Deprecated就是一个注解。

(02) @Documented -- 它的作用是说明该注解能出现在javadoc中。

(03) @Retention(RetentionPolicy.RUNTIME) -- 它的作用是指定Deprecated的策略是RetentionPolicy.RUNTIME。这就意味着,编译器会将Deprecated的信息保留在.class文件中,并且能被虚拟机读取。

(04) @Deprecated 所标注内容,不再被建议使用。

例如,若某个方法被 @Deprecated 标注,则该方法不再被建议使用。如果有开发人员试图使用或重写被@Deprecated标示的方法,编译器会给相应的提示信息。示例如下:

源码如下(DeprecatedTest.java):

1 packagecom.skywang.annotation;2

3 importjava.util.Date;4 importjava.util.Calendar;5

6 public classDeprecatedTest {7 //@Deprecated 修饰 getString1(),表示 它是建议不被使用的函数

8 @Deprecated9 private static voidgetString1(){10 System.out.println("Deprecated Method");11 }12

13 private static voidgetString2(){14 System.out.println("Normal Method");15 }16

17 //Date是日期/时间类。java已经不建议使用该类了

18 private static voidtestDate() {19 Date date = new Date(113, 8, 25);20 System.out.println(date.getYear());21 }22 //Calendar是日期/时间类。java建议使用Calendar取代Date表示“日期/时间”

23 private static voidtestCalendar() {24 Calendar cal =Calendar.getInstance();25 System.out.println(cal.get(Calendar.YEAR));26 }27

28 public static voidmain(String[] args) {29 getString1();30 getString2();31 testDate();32 testCalendar();33 }34 }

View Code

说明:

上面是eclipse中的截图,比较类中 “getString1() 和 getString2()” 以及 “testDate() 和 testCalendar()” 。

(01) getString1() 被@Deprecated标注,意味着建议不再使用getString1();所以getString1()的定义和调用时,都会一横线。这一横线是eclipse()对@Deprecated方法的处理。

getString2() 没有被@Deprecated标注,它的显示正常。

(02) testDate() 调用了Date的相关方法,而java已经建议不再使用Date操作日期/时间。因此,在调用Date的API时,会产生警告信息,途中的warnings。

testCalendar() 调用了Calendar的API来操作日期/时间,java建议用Calendar取代Date。因此,操作Calendar不回产生warning。

2.2 @Inherited

@Inherited 的定义如下:

@Documented

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.ANNOTATION_TYPE)public @interfaceInherited {

}

说明:

(01) @interface -- 它的用来修饰Inherited,意味着Inherited实现了java.lang.annotation.Annotation接口;即Inherited就是一个注解。

(02) @Documented -- 它的作用是说明该注解能出现在javadoc中。

(03) @Retention(RetentionPolicy.RUNTIME) -- 它的作用是指定Inherited的策略是RetentionPolicy.RUNTIME。这就意味着,编译器会将Inherited的信息保留在.class文件中,并且能被虚拟机读取。

(04) @Target(ElementType.ANNOTATION_TYPE) -- 它的作用是指定Inherited的类型是ANNOTATION_TYPE。这就意味着,@Inherited只能被用来标注“Annotation类型”。

(05) @Inherited 的含义是,它所标注的Annotation将具有继承性。

假设,我们定义了某个Annotaion,它的名称是MyAnnotation,并且MyAnnotation被标注为@Inherited。现在,某个类Base使用了MyAnnotation,则Base具有了“具有了注解MyAnnotation”;现在,Sub继承了Base,由于MyAnnotation是@Inherited的(具有继承性),所以,Sub也“具有了注解MyAnnotation”。

@Inherited的使用示例

源码如下(InheritableSon.java):

1 /**

2 * @Inherited 演示示例3 *4 *@authorskywang5 * @email kuiwu-wang@163.com6 */

7 packagecom.skywang.annotation;8

9 importjava.lang.annotation.Target;10 importjava.lang.annotation.ElementType;11 importjava.lang.annotation.Retention;12 importjava.lang.annotation.RetentionPolicy;13 importjava.lang.annotation.Inherited;14

15 /**

16 * 自定义的Annotation。17 */

18 @Target(ElementType.TYPE)19 @Retention(RetentionPolicy.RUNTIME)20 @Inherited21 @interfaceInheritable22 {23 }24

25 @Inheritable26 classInheritableFather27 {28 publicInheritableFather() {29 //InheritableBase是否具有 Inheritable Annotation

30 System.out.println("InheritableFather:"+InheritableFather.class.isAnnotationPresent(Inheritable.class));31 }32 }33

34 /**

35 * InheritableSon 类只是继承于 InheritableFather,36 */

37 public class InheritableSon extendsInheritableFather38 {39 publicInheritableSon() {40 super(); //调用父类的构造函数41 //InheritableSon类是否具有 Inheritable Annotation

42 System.out.println("InheritableSon:"+InheritableSon.class.isAnnotationPresent(Inheritable.class));43 }44

45 public static voidmain(String[] args)46 {47 InheritableSon is = newInheritableSon();48 }49 }

运行结果:

InheritableFather:true

InheritableSon:true

现在,我们对InheritableSon.java进行修改:注释掉“Inheritable的@Inherited注解”。

源码如下(InheritableSon.java):

1 /**

2 * @Inherited 演示示例3 *4 *@authorskywang5 * @email kuiwu-wang@163.com6 */

7 packagecom.skywang.annotation;8

9 importjava.lang.annotation.Target;10 importjava.lang.annotation.ElementType;11 importjava.lang.annotation.Retention;12 importjava.lang.annotation.RetentionPolicy;13 importjava.lang.annotation.Inherited;14

15 /**

16 * 自定义的Annotation。17 */

18 @Target(ElementType.TYPE)19 @Retention(RetentionPolicy.RUNTIME)20 //@Inherited

21 @interfaceInheritable22 {23 }24

25 @Inheritable26 classInheritableFather27 {28 publicInheritableFather() {29 //InheritableBase是否具有 Inheritable Annotation

30 System.out.println("InheritableFather:"+InheritableFather.class.isAnnotationPresent(Inheritable.class));31 }32 }33

34 /**

35 * InheritableSon 类只是继承于 InheritableFather,36 */

37 public class InheritableSon extendsInheritableFather38 {39 publicInheritableSon() {40 super(); //调用父类的构造函数41 //InheritableSon类是否具有 Inheritable Annotation

42 System.out.println("InheritableSon:"+InheritableSon.class.isAnnotationPresent(Inheritable.class));43 }44

45 public static voidmain(String[] args)46 {47 InheritableSon is = newInheritableSon();48 }49 }

View Code

运行结果:

InheritableFather:true

InheritableSon:false

对比上面的两个结果,我们发现:当注解Inheritable被@Inherited标注时,它具有继承性。否则,没有继承性。

2.3 @SuppressWarnings

@SuppressWarnings 的定义如下:

@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})

@Retention(RetentionPolicy.SOURCE)public @interfaceSuppressWarnings {

String[] value();

}

说明:

(01) @interface -- 它的用来修饰SuppressWarnings,意味着SuppressWarnings实现了java.lang.annotation.Annotation接口;即SuppressWarnings就是一个注解。

(02) @Retention(RetentionPolicy.SOURCE) -- 它的作用是指定SuppressWarnings的策略是RetentionPolicy.SOURCE。这就意味着,SuppressWarnings信息仅存在于编译器处理期间,编译器处理完之后SuppressWarnings就没有作用了。

(03) @Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE}) -- 它的作用是指定SuppressWarnings的类型同时包括TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE。

TYPE意味着,它能标注“类、接口(包括注释类型)或枚举声明”。

FIELD意味着,它能标注“字段声明”。

METHOD意味着,它能标注“方法”。

PARAMETER意味着,它能标注“参数”。

CONSTRUCTOR意味着,它能标注“构造方法”。

LOCAL_VARIABLE意味着,它能标注“局部变量”。

(04) String[] value(); 意味着,SuppressWarnings能指定参数

(05) SuppressWarnings 的作用是,让编译器对“它所标注的内容”的某些警告保持静默。例如,"@SuppressWarnings(value={"deprecation", "unchecked"})" 表示对“它所标注的内容”中的 “SuppressWarnings不再建议使用警告”和“未检查的转换时的警告”保持沉默。示例如下:

源码如下(SuppressWarningTest.java):

1 packagecom.skywang.annotation;2

3 importjava.util.Date;4

5 public classSuppressWarningTest {6

7 //@SuppressWarnings(value={"deprecation"})

8 public static voiddoSomething(){9 Date date = new Date(113, 8, 26);10 System.out.println(date);11 }12

13 public static voidmain(String[] args) {14 doSomething();15 }16 }

View Code

说明:

(01) 左边的图中,没有使用 @SuppressWarnings(value={"deprecation"}) , 而Date属于java不再建议使用的类。因此,调用Date的API时,会产生警告。

而右边的途中,使用了 @SuppressWarnings(value={"deprecation"})。因此,编译器对“调用Date的API产生的警告”保持沉默。

补充:SuppressWarnings 常用的关键字的表格

deprecation --使用了不赞成使用的类或方法时的警告

unchecked--执行了未检查的转换时的警告,例如当使用集合时没有用泛型 (Generics) 来指定集合保存的类型。

fallthrough--当 Switch 程序块直接通往下一种情况而没有 Break 时的警告。

path--在类路径、源文件路径等中有不存在的路径时的警告。

serial--当在可序列化的类上缺少 serialVersionUID 定义时的警告。finally -- 任何 finally子句不能正常完成时的警告。

all-- 关于以上所有情况的警告。

第4部分 Annotation 的作用

Annotation 是一个辅助类,它在Junit、Struts、Spring等工具框架中被广泛使用。

我们在编程中经常会使用到的Annotation作用有:

1 编译检查

Annotation具有“让编译器进行编译检查的作用”。

例如,@SuppressWarnings, @Deprecated和@Override都具有编译检查作用。

(01) 关于@SuppressWarnings和@Deprecated,已经在“第3部分”中详细介绍过了。这里就不再举例说明了。

(02) 若某个方法被 @Override的 标注,则意味着该方法会覆盖父类中的同名方法。如果有方法被@Override标示,但父类中却没有“被@Override标注”的同名方法,则编译器会报错。示例如下:

源码(OverrideTest.java):

1 packagecom.skywang.annotation;2

3 /**

4 * @Override测试程序5 *6 *@authorskywang7 * @email kuiwu-wang@163.com8 */

9 public classOverrideTest {10

11 /**

12 * toString() 在java.lang.Object中定义;13 * 因此,这里用 @Override 标注是对的。14 */

15 @Override16 publicString toString(){17 return "Override toString";18 }19

20 /**

21 * getString() 没有在OverrideTest的任何父类中定义;22 * 但是,这里却用 @Override 标注,因此会产生编译错误!23 */

24 @Override25 publicString getString(){26 return "get toString";27 }28

29 public static voidmain(String[] args) {30 }31 }

View Code

上面是该程序在eclipse中的截图。从中,我们可以发现“getString()”函数会报错。这是因为“getString() 被@Override所标注,但在OverrideTest的任何父类中都没有定义getString1()函数”。

“将getString() 上面的@Override注释掉”,即可解决该错误。

2 在反射中使用Annotation

在反射的Class, Method, Field等函数中,有许多于Annotation相关的接口。

这也意味着,我们可以在反射中解析并使用Annotation。

源码如下(AnnotationTest.java):

packagecom.skywang.annotation;importjava.lang.annotation.Annotation;importjava.lang.annotation.Target;importjava.lang.annotation.ElementType;importjava.lang.annotation.Retention;importjava.lang.annotation.RetentionPolicy;importjava.lang.annotation.Inherited;importjava.lang.reflect.Method;/*** Annotation在反射函数中的使用示例

*

*@authorskywang

* @email kuiwu-wang@163.com*/@Retention(RetentionPolicy.RUNTIME)

@interfaceMyAnnotation {

String[] value()default "unknown";

}/*** Person类。它会使用MyAnnotation注解。*/

classPerson {/*** empty()方法同时被 "@Deprecated" 和 “@MyAnnotation(value={"a","b"})”所标注

* (01) @Deprecated,意味着empty()方法,不再被建议使用

* (02) @MyAnnotation, 意味着empty() 方法对应的MyAnnotation的value值是默认值"unknown"*/@MyAnnotation

@Deprecatedpublic voidempty(){

System.out.println("\nempty");

}/*** sombody() 被 @MyAnnotation(value={"girl","boy"}) 所标注,

* @MyAnnotation(value={"girl","boy"}), 意味着MyAnnotation的value值是{"girl","boy"}*/@MyAnnotation(value={"girl","boy"})public void somebody(String name, intage){

System.out.println("\nsomebody: "+name+", "+age);

}

}public classAnnotationTest {public static void main(String[] args) throwsException {//新建Person

Person person = newPerson();//获取Person的Class实例

Class c = Person.class;//获取 somebody() 方法的Method实例

Method mSomebody = c.getMethod("somebody", new Class[]{String.class, int.class});//执行该方法

mSomebody.invoke(person, new Object[]{"lily", 18});

iteratorAnnotations(mSomebody);//获取 somebody() 方法的Method实例

Method mEmpty = c.getMethod("empty", newClass[]{});//执行该方法

mEmpty.invoke(person, newObject[]{});

iteratorAnnotations(mEmpty);

}public static voiditeratorAnnotations(Method method) {//判断 somebody() 方法是否包含MyAnnotation注解

if(method.isAnnotationPresent(MyAnnotation.class)){//获取该方法的MyAnnotation注解实例

MyAnnotation myAnnotation = method.getAnnotation(MyAnnotation.class);//获取 myAnnotation的值,并打印出来

String[] values =myAnnotation.value();for(String str:values)

System.out.printf(str+", ");

System.out.println();

}//获取方法上的所有注解,并打印出来

Annotation[] annotations =method.getAnnotations();for(Annotation annotation : annotations){

System.out.println(annotation);

}

}

}

运行结果:

somebody: lily, 18

girl, boy,

@com.skywang.annotation.MyAnnotation(value=[girl, boy])

empty

unknown,

@com.skywang.annotation.MyAnnotation(value=[unknown])

@java.lang.Deprecated()

3 根据Annotation生成帮助文档

通过给Annotation注解加上@Documented标签,能使该Annotation标签出现在javadoc中。

4 能够帮忙查看查看代码

通过@Override, @Deprecated等,我们能很方便的了解程序的大致结构。

另外,我们也可以通过自定义Annotation来实现一些功能。

点击查看:

java的annotation_Java Annotation认知(包括框架图、详细介绍、示例说明)相关推荐

  1. Java Annotation认知(包括框架图、详细介绍、示例说明)

    摘要 Java Annotation是JDK5.0引入的一种注释机制. 网上很多关于Java Annotation的文章,看得人眼花缭乱.Java Annotation本来很简单的,结果说的人没说清楚 ...

  2. JAVA导出Excel通用工具类——第一篇:详细介绍POI 导出excel的多种复杂情况,包括动态设置筛选、动态合并横向(纵向)单元格等多种复杂情况——保姆级别,真的不能再详细了,代码拿来即用)

    JAVA导出Excel通用工具--第一篇:详细介绍POI 导出excel的多种复杂情况,包括动态设置筛选.动态合并横向(纵向)单元格等多种复杂情况--保姆级别,真的不能再详细了,封装通用工具类,代码拿 ...

  3. java kryo register_java相关:Kryo框架使用方法代码示例

    java相关:Kryo框架使用方法代码示例 发布于 2021-1-21| 复制链接 摘记: Kryo框架的source已移至https://github.com/EsotericSoftware/kr ...

  4. Java的JVM性能监控与故障处理工具详细介绍以及使用案例

    给一个系统定位问题的时候,知识.经验是关键基础,数据是依据.工具是运用知识处理数据的手段.这里说的数据包括:运行日志.异常堆栈.GC日志.线程快照文件(threaddump/javacore文件).堆 ...

  5. java lambda 局部变量_java Lambda表达式访问局部变量详细介绍

    此前给大家带来了java Lambda表达式访问成员变量详细介绍,下面就要继续给大家介绍java Lambda表达式访问局部变量的内容,一起通过简单的文章来进行了解吧. 对于成员变量的访问Lambda ...

  6. ggridges包—峰峦图详细介绍

    上次可视化系列说了瀑布图.它可以用于展示拥有相同的X轴变量数据(如相同的时间序列).不同的Y轴离散型变量(如不同的类别变量)和Z轴数值变量. 本节使用的峰峦图也可以很好地展示瀑布图的数据信息.它们对于 ...

  7. 从程序员到CTO的Java技术路线图 JAVA职业规划 JAVA职业发展路线图 系统后台框架图、前端工程师技能图 B2C电子商务基础系统架构解析...

    http://zz563143188.iteye.com/blog/1877266在技术方面无论我们怎么学习,总感觉需要提升自已不知道自己处于什么水平了.但如果有清晰的指示图供参考还是非常不错的,这样 ...

  8. java职业发展路线图_从程序员到CTO的Java技术路线图 JAVA职业规划 JAVA职业发展路线图 系统后台框架图、前端工程师技能图 B2C电子商务基础系统架构解析...

    http://zz563143188.iteye.com/blog/1877266在技术方面无论我们怎么学习,总感觉需要提升自已不知道自己处于什么水平了.但如果有清晰的指示图供参考还是非常不错的,这样 ...

  9. JAVA——Java后端技术体系韩顺平框架图_韩顺平Java基础学习路线图

    第一阶段:Java基础 变量.控制结构.OOP(封装,继承,多态).数组.Java API.异常和处理.集合.泛型.IO.反射.网络通信 第二阶段:Java高级 Java多线程/高并发 1.1 并发基 ...

最新文章

  1. mysql sql w3cschool_SQL复习(w3school)笔记
  2. 我叫Java,2019年总结,大家请查收
  3. 关联规则概念、啤酒加尿布引出购物篮分析、频繁项集、支持度+置信度+提升度
  4. 优化春运服务 北京铁路局在车站设置哺乳室等设施
  5. linux教程for语句,Shell脚本for循环语句简明教程
  6. wdpc配置https打不开
  7. Some Essential JavaScript Questions And Answers(3)
  8. 后端技术:ELK不香了?企业级日志平台新框架 Graylog介绍
  9. ncut算法matlab实现,ncut_multiscale_1_6 经典的图像分割算法 的Matlab代码。 238万源代码下载- www.pudn.com...
  10. python模拟qq空间登录_python selenium模拟登录163邮箱和QQ空间
  11. 《大教堂与市集》读后感
  12. 超链接、插入子报表、网页框
  13. Springboot的Mybatis拦截器实现
  14. python控制苹果手机触摸屏失灵怎么办_iPhone手机触屏不灵敏怎么办 触屏失灵乱跳等问题解决方法大全必看...
  15. 情不知所起,一 网 而深
  16. Python将图片转化成文字
  17. Linux以太网卡架构解析-MAC层和PHY层
  18. 向左还是向右?聊聊中台建设中的那些纠结事
  19. 个性化实时音乐推荐系统-毕业设计
  20. JS 实现页面跳转的几种方法

热门文章

  1. c++ 读文件_Linux文件(文件夹)详解
  2. extundelete安装_Linux数据安全工具:数据恢复软件extundelete概述
  3. 关于DCF(判别相关滤波器)的闭式解详细推导
  4. vc2010中设置ipch与sdf的位置
  5. go语言中goroutine池
  6. sock使用UDP协议进行广播发送数据
  7. mysql 最大并发连接数
  8. 过滤器、拦截器、监听器的区别与使用
  9. leetcode第一题两数相加
  10. S5PV210开发 -- 驱动开发相关硬件简介