`

《Java Annotation 高级应用》

    博客分类:
  • Java
阅读更多
前言:
前不久在matrix上先后发表了《java annotation 入门》 、《java annotation 手册》 两 篇文章,比较全面的对java annotation的语法、原理、使用三方面进行了阐述。由于《入门》中的简单例程虽然简单明了的说明了annotation用法,但给大家的感觉可能 是意犹未见,所以在此行文《java annotation 高级应用》,具体实例化解释annotation和annotation processing tool(APT)的使用。望能对各位的有所帮助。

一、摘要:
《java annotation 高级应用》具体实例化解释annotation和annotation processing tool(APT)的使用。望能对各位的有所帮助。本文列举了用于演示annotation的BRFW演示框架、演示APT的apt代码实例,并对其进行 较为深度的分析,希望大家多多提意见。

二、annotation实例分析
1.BRFW(Beaninfo Runtime FrameWork)定义:
本人编写的一个annotation功能演示框架。顾名思义,BRFW就是在运行时取得bean信息的框架。

2.BRFW的功能:
A.源代码级annotation :在bean的源代码中使用annotation定义bean的信息;
B.运行时获取bean数据 :在运行时分析bean class中的annotation,并将当前bean class中field信息取出,功能类似xdoclet;
C.运行时bean数据的xml绑定 :将获得的bean数据构造为xml文件格式展现。熟悉j2ee的朋友知道,这个功能类似jaxb。

3.BRFW框架:
BRFW主要包含以下几个类:
A.Persistent类 :定义了用于修饰类的固有类型成员变量的annotation。
B.Exportable类 :定义了用于修饰Class的类型的annotation。
C.ExportToXml类 :核心类,用于完成BRFW的主要功能:将具有Exportable Annotation的bean对象转换为xml格式文本。
D.AddressForTest类 :被A和B修饰过的用于测试目的的地址bean类。其中包含了地址定义所必需的信息:国家、省级、城市、街道、门牌等。
E.AddressListForTest类 : 被A和B修饰过的友人通讯录bean类。其中包含了通讯录所必备的信息:友人姓名、年龄、电话、住址(成员为AddressForTest类型的 ArrayList)、备注。需要说明的是电话这个bean成员变量是由字符串类型组成的ArrayList类型。由于朋友的住址可能不唯一,故这里的住 址为由AddressForTest类型组成的ArrayList。
从上面的列表中,可以发现A、B用于修饰bean类和其类成员;C主要用于取出bean类的数据并将其作xml绑定,代码中使用了E作为测试类;E中可能包含着多个D。
在了解了这个简单框架后,我们来看一下BRFW的代码吧!

4.BRFW源代码分析:
A.Persistent类:
清单1:

package com.bjinfotech.practice.annotation.runtimeframework;



import java.lang.annotation.*;



/**

 * 用于修饰类的固有类型成员变量的annotation

 * @author cleverpig

 *

 */

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.FIELD)

public @interface Persistent { 

        String value() default "";

}



B.Exportable类:
清单2:

package com.bjinfotech.practice.annotation.runtimeframework;



import java.lang.annotation.*;



/**

 * 用于修饰类的类型的annotation

 * @author cleverpig

 *

 */

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.TYPE)

public @interface Exportable {

        //名称

        String name() default "";

        //描述

        String description() default "";

        //省略name和description后,用来保存name值

        String value() default "";

        

}



C.AddressForTest类:
清单3:

package com.bjinfotech.practice.annotation.runtimeframework;



/**

 * 用于测试的地址类

 * @author cleverpig

 *

 */

@Exportable("address")

public class AddressForTest {

        //国家

        @Persistent

        private String country=null;

        

        //省级

        @Persistent

        private String province=null;

        

        //城市

        @Persistent

        private String city=null;

        

        //街道

        @Persistent

        private String street=null;



        //门牌

        @Persistent

        private String doorplate=null;

        

        public AddressForTest(String country,String province,

                        String city,String street,String doorplate){

                this.country=country;

                this.province=province;

                this.city=city;

                this.street=street;

                this.doorplate=doorplate;

        }

        

}



D.AddressListForTest类:
清单4:

package com.bjinfotech.practice.annotation.runtimeframework;



import java.util.*;



/**

 * 友人通讯录

 * 包含:姓名、年龄、电话、住址(多个)、备注

 * @author cleverpig

 *

 */

@Exportable(name="addresslist",description="address list")

public class AddressListForTest {

        //友人姓名

        @Persistent

        private String friendName=null;

        

        //友人年龄

        @Persistent

        private int age=0;

        

        //友人电话

        @Persistent

        private ArrayList<String> telephone=null;

        

        //友人住址:家庭、单位

        @Persistent

        private ArrayList<AddressForTest> AddressForText=null;

        

        //备注

        @Persistent

        private String note=null;

        

        public AddressListForTest(String name,int age,

                        ArrayList<String> telephoneList, 

                        ArrayList<AddressForTest> addressList,

                        String note){

                this.friendName=name;

                this.age=age;

                this.telephone=new ArrayList<String>(telephoneList);

                this.AddressForText=new ArrayList<AddressForTest>(addressList);

                this.note=note;

                

        }

}



E.ExportToXml类:
清单5:

package com.bjinfotech.practice.annotation.runtimeframework;



import java.lang.reflect.Field;

import java.util.Collection;

import java.util.Iterator;

import java.util.Map;

import java.util.ArrayList;



/**

 * 将具有Exportable Annotation的对象转换为xml格式文本 

 * @author cleverpig

 *

 */

public class ExportToXml {

        /**

         * 返回对象的成员变量的值(字符串类型)

         * @param field 对象的成员变量

         * @param fieldTypeClass 对象的类型

         * @param obj 对象

         * @return 对象的成员变量的值(字符串类型)

         */

        private String getFieldValue(Field field,Class fieldTypeClass,Object obj){

                String value=null;

                

                try{

                        if (fieldTypeClass==String.class){

                                value=(String)field.get(obj);

                        }

                        else if (fieldTypeClass==int.class){

                                value=Integer.toString(field.getInt(obj));

                        }

                        else if (fieldTypeClass==long.class){

                                value=Long.toString(field.getLong(obj));

                        }

                        else if (fieldTypeClass==short.class){

                                value=Short.toString(field.getShort(obj));

                        }

                        else if (fieldTypeClass==float.class){

                                value=Float.toString(field.getFloat(obj));

                        }

                        else if (fieldTypeClass==double.class){

                                value=Double.toString(field.getDouble(obj));

                        }

                        else if (fieldTypeClass==byte.class){

                                value=Byte.toString(field.getByte(obj));

                        }

                        else if (fieldTypeClass==char.class){

                                value=Character.toString(field.getChar(obj));

                        }

                        else if (fieldTypeClass==boolean.class){

                                value=Boolean.toString(field.getBoolean(obj));

                        }

                }

                catch(Exception ex){

                        ex.printStackTrace();

                        value=null;

                }

                return value;

        }

        

        /**

         * 输出对象的字段,当对象的字段为Collection或者Map类型时,要调用exportObject方法继续处理

         * @param obj 被处理的对象

         * @throws Exception

         */

        public void exportFields(Object obj) throws Exception{

                Exportable exportable=obj.getClass().getAnnotation(Exportable.class);        

                if (exportable!=null){

                        if (exportable.value().length()>0){

//                                System.out.println("Class annotation Name:"+exportable.value());

                        }

                        else{

//                                System.out.println("Class annotation Name:"+exportable.name());

                        }

                }

                else{

//                        System.out.println(obj.getClass()+"类不是使用Exportable标注过的");

                }

                

                //取出对象的成员变量

                Field[] fields=obj.getClass().getDeclaredFields();

                

                for(Field field:fields){

                        //获得成员变量的标注

                        Persistent fieldAnnotation=field.getAnnotation(Persistent.class);

                        if (fieldAnnotation==null){

                                continue;

                        }

                        //重要:避免java虚拟机检查对私有成员的访问权限

                        field.setAccessible(true);

                        Class typeClass=field.getType();

                        String name=field.getName();

                        String value=getFieldValue(field,typeClass,obj);

                        

                        //如果获得成员变量的值,则输出

                        if (value!=null){

                                System.out.println(getIndent()+"<"+name+">\n"

                                                +getIndent()+"\t"+value+"\n"+getIndent()+"</"+name+">");

                        }

                        //处理成员变量中类型为Collection或Map

                        else if ((field.get(obj) instanceof Collection)||

                                        (field.get(obj) instanceof Map)){

                                exportObject(field.get(obj));

                        }

                        else{

                                exportObject(field.get(obj));

                        }

                        

                }

        }

        

        //缩进深度

        int levelDepth=0;

        //防止循环引用的检查者,循环引用现象如:a包含b,而b又包含a

        Collection<Object> cyclicChecker=new ArrayList<Object>();

        

        /**

         * 返回缩进字符串

         * @return

         */

        private String getIndent(){

                String s="";

                for(int i=0;i<levelDepth;i++){

                        s+="\t";

                }

                return s;

        }

        /**

         * 输出对象,如果对象类型为Collection和Map类型,则需要递归调用exportObject进行处理

         * @param obj

         * @throws Exception

         */

        public void exportObject(Object obj) throws Exception{

                Exportable exportable=null;

                String elementName=null;

                

                //循环引用现象处理

                if (cyclicChecker.contains(obj)){

                        return;

                }

                

                cyclicChecker.add(obj);

                

                //首先处理Collection和Map类型

                if (obj instanceof Collection){

                        for(Iterator i=((Collection)obj).iterator();i.hasNext();){

                                exportObject(i.next());

                        }

                }

                else if (obj instanceof Map){

                        for(Iterator i=((Map)obj).keySet().iterator();i.hasNext();){

                                exportObject(i.next());

                        }

                }

                else{



                        exportable=obj.getClass().getAnnotation(Exportable.class);

                        //如果obj已经被Exportable Annotation修饰过了(注意annotation是具有继承性的),

                        //则使用其name作为输出xml的元素name

                        if (exportable!=null){

                                if (exportable.value().length()>0){

                                        elementName=exportable.value();

                                }

                                else{

                                        elementName=exportable.name();

                                }

                        }

                        //未被修饰或者Exportable Annotation的值为空字符串,

                        //则使用类名作为输出xml的元素name

                        if (exportable==null||elementName.length()==0){

                                elementName=obj.getClass().getSimpleName();

                        }

                        //输出xml元素头

                        System.out.println(getIndent()+"<"+elementName+">");

                        levelDepth++;

                        //如果没有被修饰,则直接输出其toString()作为元素值

                        if (exportable==null){

                                System.out.println(getIndent()+obj.toString());

                        }

                        //否则将对象的成员变量导出为xml

                        else{

                                exportFields(obj);

                        }

                        levelDepth--;

                        //输出xml元素结尾

                        System.out.println(getIndent()+"</"+elementName+">");

                        

                }

                cyclicChecker.remove(obj);

        }

        

        public static void main(String[] argv){

                try{

                        AddressForTest ad=new AddressForTest("China","Beijing",

                                        "Beijing","winnerStreet","10");

                        

                        ExportToXml test=new ExportToXml();

                        

                        ArrayList<String> telephoneList=new ArrayList<String>();

                        telephoneList.add("66608888");

                        telephoneList.add("66608889");

                        

                        ArrayList<AddressForTest> adList=new ArrayList<AddressForTest>();

                        adList.add(ad);

                        

                        AddressListForTest adl=new AddressListForTest("coolBoy",

                                        18,telephoneList,adList,"some words");

                        

                        test.exportObject(adl);

                }

                catch(Exception ex){

                        ex.printStackTrace();

                }

        }

}



在ExportToXml类之前的类比较简单,这里必须说明一下ExportToXml类:此类的核心函数是exportObject和 exportFields方法,前者输出对象的xml信息,后者输出对象成员变量的信息。由于对象类型和成员类型的多样性,所以采取了以下的逻辑:

在exportObject方法中,当对象类型为Collection和Map类型时,则需要递归调用exportObject进行处理;
而如果对象类型不是Collection和Map类型的话,将判断对象类是否被Exportable annotation修饰过:
如果没有被修饰,则直接输出<对象类名>对象.toString()</对象类名>作为xml绑定结果的一部分;
如果被修饰过,则需要调用exportFields方法对对象的成员变量进行xml绑定。

在 exportFields方法中,首先取出对象的所有成员,然后获得被Persisitent annotation修饰的成员。在其后的一句:field.setAccessible(true)是很重要的,因为bean类定义中的成员访问修饰都 是private,所以为了避免java虚拟机检查对私有成员的访问权限,加上这一句是必需的。接着后面的语句便是输出<成员名>成员 值</成员名>这样的xml结构。像在exportObject方法中一般,仍然需要判断成员类型是否为Collection和Map类型, 如果为上述两种类型之一,则要在exportFields中再次调用exportObject来处理这个成员。

在main方法中,本人编写了一段演示代码:建立了一个由单个友人地址类(AddressForTest)组成的ArrayList作为通讯录类(AddressForTest)的成员的通讯录对象,并且输出这个对象的xml绑定,运行结果如下:

清单6:

<addresslist>

        <friendName>

                coolBoy

        </friendName>

        <age>

                18

        </age>

        <String>

                66608888

        </String>

        <String>

                66608889

        </String>

        <address>

                <country>

                        China

                </country>

                <province>

                        Beijing

                </province>

                <city>

                        Beijing

                </city>

                <street>

                        winnerStreet

                </street>

                <doorplate>

                        10

                </doorplate>

        </address>

        <note>

                some words

        </note>

</addresslist>



三、APT实例分析:
1.何谓APT?
根 据sun官方的解释,APT(annotation processing tool)是一个命令行工具,它对源代码文件进行检测找出其中的annotation后,使用annotation processors来处理annotation。而annotation processors使用了一套反射API并具备对JSR175规范的支持。
annotation processors处理annotation的基本过程如下:首先,APT运行annotation processors根据提供的源文件中的annotation生成源代码文件和其它的文件(文件具体内容由annotation processors的编写者决定),接着APT将生成的源代码文件和提供的源文件进行编译生成类文件。
简单的和前面所讲的annotation 实例BRFW相比,APT就像一个在编译时处理annotation的javac。而且从sun开发者的blog中看到,java1.6 beta版中已将APT的功能写入到了javac中,这样只要执行带有特定参数的javac就能达到APT的功能。

2.为何使用APT?
使 用APT主要目的是简化开发者的工作量,因为APT可以在编译程序源代码的同时,生成一些附属文件(比如源文件、类文件、程序发布描述文字等),这些附属 文件的内容也都是与源代码相关的。换句话说,使用APT就是代替了传统的对代码信息和附属文件的维护工作。使用过hibernate或者beehive等 软件的朋友可能深有体会。APT可以在编译生成代码类的同时将相关的文件写好,比如在使用beehive时,在代码中使用annotation声明了许多 struct要用到的配置信息,而在编译后,这些信息会被APT以struct配置文件的方式存放。

3.如何定义processor?
A.APT工作过程:
从 整个过程来讲,首先APT检测在源代码文件中哪些annotation存在。然后APT将查找我们编写的annotation processor factories类,并且要求factories类提供处理源文件中所涉及的annotation的annotation processor。接下来,一个合适的annotation processors将被执行,如果在processors生成源代码文件时,该文件中含有annotation,则APT将重复上面的过程直到没有新文 件生成。

B.编写annotation processors:
编写一个annotation processors需要使用java1.5 lib目录中的tools.jar提供的以下4个包:
com.sun.mirror.apt: 和APT交互的接口;
com.sun.mirror.declaration: 用于模式化类成员、类方法、类声明的接口;
com.sun.mirror.type: 用于模式化源代码中类型的接口;
com.sun.mirror.util: 提供了用于处理类型和声明的一些工具。

每 个processor实现了在com.sun.mirror.apt包中的AnnotationProcessor接口,这个接口有一个名为 “process”的方法,该方法是在APT调用processor时将被用到的。一个processor可以处理一种或者多种annotation类 型。
一个processor实例被其相应的工厂返回,此工厂为AnnotationProcessorFactory接口的实现。APT将调用工 厂类的getProcessorFor方法来获得processor。在调用过程中,APT将提供给工厂类一个 AnnotationProcessorEnvironment 类型的processor环境类对象,在这个环境对象中,processor将找到其执行所需要的每件东西,包括对所操作的程序结构的参考,与APT通讯 并合作一同完成新文件的建立和警告/错误信息的传输。

提供工厂类有两个方式:通过APT的“-factory”命令行参数提供,或者让工厂类在APT的发现过程中被自动定位(关于发现过程详细介绍请看http://java.sun.com/j2se/1.5.0/docs/guide/apt/GettingStarted.html )。前者对于一个已知的factory来讲是一种主动而又简单的方式;而后者则是需要在jar文件的META-INF/services目录中提供一个特定的发现路径:
在 包含factory类的jar文件中作以下的操作:在META-INF/services目录中建立一个名为 com.sun.mirror.apt.AnnotationProcessorFactory 的UTF-8编码文件,在文件中写入所有要使用到的factory类全名,每个类为一个单独行。

4.一个简单的APT实例分析:
A.实例构成:
Review类:定义Review Annotation;
ReviewProcessorFactory类:生成ReviewProcessor的工厂类;
ReviewProcessor类:定义处理Review annotation的Processor;
ReviewDeclarationVisitor类:定义Review annotation声明访问者,ReviewProcessor将要使用之对Class进行访问。
runapt.bat:定义了使用自定义的ReviewProcessor对Review类源代码文件进行处理的APT命令行。

B.Review类:
清单7:

package com.bjinfotech.practice.annotation.apt;



/**

 * 定义Review Annotation

 * @author cleverpig

 *

 */

public @interface Review {

        public static enum TypeEnum{EXCELLENT,NICE,NORMAL,BAD};

        TypeEnum type();

        String name() default "Review";

}



C.ReviewProcessorFactory类:
清单8:

package com.bjinfotech.practice.annotation.apt;



import java.util.Collection;

import java.util.Set;

import java.util.Arrays;

import com.sun.mirror.apt.*;

import com.sun.mirror.declaration.AnnotationTypeDeclaration;

import com.sun.mirror.apt.AnnotationProcessorEnvironment;

//请注意为了方便,使用了静态import

import static java.util.Collections.unmodifiableCollection;

import static java.util.Collections.emptySet;



/**

 * 生成ReviewProcessor的工厂类

 * @author cleverpig

 *

 */

public class ReviewProcessorFactory implements AnnotationProcessorFactory{

        /**

         * 获得针对某个(些)类型声明定义的Processor

         * @param atds 类型声明集合

         * @param env processor环境

         */

        public AnnotationProcessor getProcessorFor(

                        Set<AnnotationTypeDeclaration> atds, 

                        AnnotationProcessorEnvironment env){

                return new ReviewProcessor(env);

        }

        /**

         * 定义processor所支持的annotation类型

         * @return processor所支持的annotation类型的集合

         */

        public Collection<String>         supportedAnnotationTypes(){

                //“*”表示支持所有的annotation类型

                //当然也可以修改为“foo.bar.*”、“foo.bar.Baz”,来对所支持的类型进行修饰

            return unmodifiableCollection(Arrays.asList("*"));

    }

        

        /**

         * 定义processor支持的选项

         * @return processor支持选项的集合

         */

        public Collection<String>         supportedOptions(){

                //返回空集合

            return emptySet();

    }

        

        public static void main(String[] argv){

                System.out.println("ok");

        }

}



D.ReviewProcessor类:
清单9:

package com.bjinfotech.practice.annotation.apt;



import com.sun.mirror.apt.AnnotationProcessor;

import com.sun.mirror.apt.AnnotationProcessorEnvironment;

import com.sun.mirror.declaration.TypeDeclaration;

import com.sun.mirror.util.DeclarationVisitors;

import com.sun.mirror.util.DeclarationVisitor;



/**

 * 定义Review annotation的Processor

 * @author cleverpig

 *

 */

public class ReviewProcessor implements AnnotationProcessor{

        //Processor所工作的环境

        AnnotationProcessorEnvironment env=null;

        

        /**

         * 构造方法

         * @param env 传入processor环境

         */

        public ReviewProcessor(AnnotationProcessorEnvironment env){

                this.env=env;

        }

        

        /**

         * 处理方法:查询processor环境中的类型声明,

         */

        public void process(){

                //查询processor环境中的类型声明

                for(TypeDeclaration type:env.getSpecifiedTypeDeclarations()){

                        //返回对类进行扫描、访问其声明时使用的DeclarationVisitor,

                        //传入参数:new ReviewDeclarationVisitor(),为扫描开始前进行的对类声明的处理

                        //        DeclarationVisitors.NO_OP,表示在扫描完成时进行的对类声明不做任何处理

                        DeclarationVisitor visitor=DeclarationVisitors.getDeclarationScanner(

                                        new ReviewDeclarationVisitor(),DeclarationVisitors.NO_OP);

                        //应用DeclarationVisitor到类型

                        type.accept(visitor);

                }

        }

}



E.ReviewDeclarationVisitor类:
清单10:

package com.bjinfotech.practice.annotation.apt;



import com.sun.mirror.util.*;

import com.sun.mirror.declaration.*;



/**

 * 定义Review annotation声明访问者

 * @author cleverpig

 *

 */

public class ReviewDeclarationVisitor extends SimpleDeclarationVisitor{

        /**

         * 定义访问类声明的方法:打印类声明的全名

         * @param cd 类声明对象

         */

        public void visitClassDeclaration(ClassDeclaration cd){

                System.out.println("获取Class声明:"+cd.getQualifiedName());

        }

        

        public void visitAnnotationTypeDeclaration(AnnotationTypeDeclaration atd){

                System.out.println("获取Annotation类型声明:"+atd.getSimpleName());

        }

        

        public void visitAnnotationTypeElementDeclaration(AnnotationTypeElementDeclaration aed){

                System.out.println("获取Annotation类型元素声明:"+aed.getSimpleName());

        }

}



F.runapt.bat文件内容如下:
清单11:

E:

rem 项目根目录

set PROJECT_ROOT=E:\eclipse3.1RC3\workspace\tigerFeaturePractice

rem 包目录路径

set PACKAGEPATH=com\bjinfotech\practice\annotation\apt

rem 运行根路径

set RUN_ROOT=%PROJECT_ROOT%\build

rem 源文件所在目录路径

set SRC_ROOT=%PROJECT_ROOT%\test

rem 设置Classpath

set CLASSPATH=.;%JAVA_HOME%;%JAVA_HOME%/lib/tools.jar;%RUN_ROOT%



cd %SRC_ROOT%\%PACKAGEPATH%

apt -nocompile -factory com.bjinfotech.practice.annotation.apt.ReviewProcessorFactory  ./*.java



四、参考资源:
http://java.sun.com/j2se/1.5.0/docs/guide/apt/GettingStarted.html
作者的Blog:http://blog.matrix.org.cn/page/cleverpig
                         --摘自《Java Annotation 高级应用》
分享到:
评论
2 楼 pandengzhegt 2011-08-23  
我也敬礼!
1 楼 yingzhor 2011-03-07  
好文! 敬礼!

相关推荐

    Java Annotation注解.doc

    Java Annotation,也称为注解,是Java编程语言中的一种元数据机制,用于向编译器、JVM或工具提供有关代码的附加信息。这些信息不直接影响代码的执行,但...在《Java Annotation高级应用》中,可能会涵盖这些高级主题。

    java annotation入门

    Java 注解(Annotation)是 Java 语言中的一个重要特性,它为程序员提供了元数据,即关于...对于更高级的用法,如自定义注解生成 XML 映射文件等,可以进一步阅读《Java Annotation 高级应用》等相关资料进行深入学习。

    Java的高级应用

    Java的高级应用涵盖了诸如并发处理、垃圾回收、网络编程、多线程、反射、注解、泛型、IO流、NIO、数据库连接池、设计模式等多方面的内容。这些知识点对于提升Java程序员的技能水平至关重要,也是深入理解Android开发...

    Java Annotation入门.doc

    Java 注解(Annotation)是 Java 语言中的一个重要特性,它为元编程提供了强大的支持。注解在 Java 5.0 版本引入,允许开发者定义、使用...随着技能的提升,还可以探索更高级的应用,如自定义注解生成 XML 映射文件等。

    Java.Annotation

    **Annotation 高级特性** - **Retention Policy**:通过`@Retention`,我们可以控制Annotation的生命周期,例如保留在源代码、编译后的字节码或运行时。常见的策略有`SOURCE`(只存在于源码)、`CLASS`(编译后丢弃...

    JAVA编程高级PPT(高级版,比较详细)

    这份资源涵盖了Java语言的高级特性和实践应用,旨在帮助学习者深入理解Java平台的精髓,提升编程技能,以达到更高效、更专业地进行软件开发。 首先,PPT可能涉及了Java集合框架的深入讲解。集合框架是Java编程中...

    比XML更好用的JavaAnnotation2022优秀文档.ppt

    Java社区中有许多优秀的开源库利用注解实现了更高级的功能。比如: - Javassist和ASM:这两个库允许在运行时动态修改类,包括添加或修改注解,这对于AOP(面向切面编程)和其他动态代理技术非常有用。 - CDI...

    Annotation手册

    Annotation是Java语言中的一种特性,它为程序元素(如包、类、方法、变量等)提供了附加信息。...随着Java版本的升级,Annotation的应用场景和能力也在不断扩大,成为了现代Java开发不可或缺的一部分。

    java高级教程JAVA高级教程

    在Java的高级教程中,我们通常会深入探讨以下几个关键知识点: 1. **多线程**:Java提供了内置的多线程支持,使得程序可以同时执行多个任务。线程的创建、同步、通信以及线程池的使用是高级Java开发人员必须掌握的...

    java中高级面试题十大总结

    Java作为一门广泛使用的编程语言,其中高级面试题往往涵盖了多方面的知识点,旨在考察候选人的技术深度和广度。以下是对这些面试题的详细解析: 1. **内存管理与垃圾回收** - Java的内存分为堆内存(Heap)和栈...

    java高级应用简笔

    ### Java高级应用知识点详解 #### 一、自定义注解 **1.1 注解概述** 在Java中,注解是一种元数据,用于提供有关程序元素(如类、方法、字段等)的附加信息。注解本身并不改变程序的行为,但它们可以被工具或框架...

    Java+Annotation.pdf

    ### Java注解(Annotation)详解 #### 一、引言 在Java开发过程中,经常会遇到需要为代码添加元数据的...随着对注解的理解逐渐加深,开发者还可以探索更多高级应用场景,如使用自定义注解生成JavaBean映射XML文件等。

    单元学习javaAnnotation.pdf

    它在Java 5.0版本中引入,并通过提供一个形式化的方式来定义元数据,从而使得开发者可以将注解应用到Java代码中,以此实现各种不同的功能。 在Java中,注解不会直接影响程序的操作,即它们不会在程序运行时直接发挥...

    完整版 Java高级教程 Java语言程序设计 第7章 Java注解(共10页).ppt

    Java注解(Annotation)是Java语言的一个重要特性,自JDK 5.0引入以来,它已经成为编写可维护和可扩展代码的关键工具。注解是一种形式化的元数据,提供了将信息附加到源代码的能力,这些信息可以被编译器、IDE、构建...

    java高级编程ppt

    Java高级编程是软件开发专业的重要课程,主要针对已经掌握基础编程概念的学生,旨在深化他们对Java这门语言的理解和应用能力。在这个阶段的学习中,学生将深入探讨Java的高级特性和最佳实践,以便在未来的职业生涯...

    java高级理论-1

    6. **集合框架**:Java集合框架包括接口(如List, Set, Queue)和实现(如ArrayList, HashSet, HashMap),视频可能讨论了它们之间的区别和应用场景。 7. **I/O流**:介绍Java的输入/输出系统,包括文件操作、网络...

    Java高级课程

    Java高级课程涵盖了Java编程语言的深入理解和应用,是开发者进阶必备的知识体系。在这个课程中,你将学习到一系列高级主题,旨在提升你的编程技能,提高代码效率和可维护性。以下是一些主要的知识点: 1. **多线程*...

    高级JAVA源代码

    在“高级JAVA源代码”这个资源中,我们可以深入学习和探讨Java编程的高级概念和实践。这份资料旨在为Java开发者提供全面的指导,无论是初学者还是有经验的开发者,都能从中受益匪浅。通过详尽的讲解和示例代码,这份...

Global site tag (gtag.js) - Google Analytics