hadoop伪分布式模式中的一个问题,这是怎么回事儿呀

Java注解(自定义方法注解及测试)_Java_ThinkSAAS
Java注解(自定义方法注解及测试)
Java注解(自定义方法注解及测试)
内容来源: 网络
目标,创建一个方法注解,我们能够初始化时执行该方法,并可以给该方法传入注解的参数值
假设我们设计一个 sayHello(String name) 方法,给该方法做个注解,初始时使用注解传入"小明"
[java]
public class HelloWorldStub { 
@HelloWorldAnnotation(name = "小明") 
public String sayHello(String name) { 
if (name == null ) { 
name = ""; 
return name + " say hello world!"; 
public class HelloWorldStub {
(name = "小明")
public String sayHello(String name) {
if (name == null ) {
name = "";
return name + " say hello world!";
定义注解
[java]
import java.lang.annotation.D 
import java.lang.annotation.ElementT 
import java.lang.annotation.R 
import java.lang.annotation.RetentionP 
import java.lang.annotation.T 
@Retention(RetentionPolicy.RUNTIME)//注解会在class中存在,运行时可通过反射获取
@Target(ElementType.METHOD)//目标是方法
@Documented//文档生成时,该注解将被包含在javadoc中,可去掉
public @interface HelloWorldAnnotation { 
public String name() default ""; 
import java.lang.annotation.D
import java.lang.annotation.ElementT
import java.lang.annotation.R
import java.lang.annotation.RetentionP
import java.lang.annotation.T
@Retention(RetentionPolicy.RUNTIME)//注解会在class中存在,运行时可通过反射获取
@Target(ElementType.METHOD)//目标是方法
@Documented//文档生成时,该注解将被包含在javadoc中,可去掉
public @interface HelloWorldAnnotation {
public String name() default "";
我们的测试类 
[java]
import java.lang.reflect.InvocationTargetE 
import org.junit.T 
import static org.junit.Assert.assertE 
public class TestHelloWorldAnnotation { 
@Test 
public void testHello() throws IllegalArgumentException, 
IllegalAccessException, InvocationTargetException, 
SecurityException, NoSuchMethodException, InstantiationException { 
//定义操作类
ParseAnnotationStub parse = new ParseAnnotationStub(); 
//假设我们知道类HelloWorldStub使用了注解,执行HelloWorldStub中带注解的方法
//判断是否使用了注解的name()方法,设置name = "小明",并返回"小明 say hello world!"
String returnValue = parse.parseMethod(HelloWorldStub.class); 
assertEquals("小明 say hello world!", returnValue) ; 
import java.lang.reflect.InvocationTargetE
import org.junit.T
import static org.junit.Assert.assertE
public class TestHelloWorldAnnotation {
public void testHello() throws IllegalArgumentException,
IllegalAccessException, InvocationTargetException,
SecurityException, NoSuchMethodException, InstantiationException {
//定义操作类
ParseAnnotationStub parse = new ParseAnnotationStub();
//假设我们知道类HelloWorldStub使用了注解,执行HelloWorldStub中带注解的方法
//判断是否使用了注解的name()方法,设置name = "小明",并返回"小明 say hello world!"
String returnValue = parse.parseMethod(HelloWorldStub.class);
assertEquals("小明 say hello world!", returnValue) ;
执行的注解方法的操作类
[java]
import java.lang.reflect.InvocationTargetE 
import java.lang.reflect.M 
public class ParseAnnotationStub { 
//包装了下基本的方法反射(范围是带了我们特定注解的方法)
//传入我们要执行的类型,所以我们时常发现某些框架要我们定义好类查找的范围,或前后缀什么的
//可以设置返回值为空void 或者Object通用,这里我们为了测试采用String返回值
public String parseMethod(Class&?& clazz) throws IllegalArgumentException, 
IllegalAccessException, InvocationTargetException, 
SecurityException, NoSuchMethodException, InstantiationException { 
//获得该对象
Object obj = clazz.getConstructor(new Class[]{}).newInstance(new Object[]{}); 
//变量该对象的方法
for (Method method : clazz.getDeclaredMethods()) { 
//获取方法的注解,
HelloWorldAnnotation say = method.getAnnotation(HelloWorldAnnotation.class); 
if (say != null) { 
//这里我们先前定义了
UseHelloWorld.sayHello(String name)方法
//这里可以从注解中获取值,或者直接运行,或者缓存该对象方法
String name = say.name(); 
return (String)method.invoke(obj, name); 
return ""; 
import java.lang.reflect.InvocationTargetE
import java.lang.reflect.M
public class ParseAnnotationStub {
//包装了下Java基本的方法反射(范围是带了我们特定注解的方法)
//传入我们要执行的类型,所以我们时常发现某些框架要我们定义好类查找的范围,或前后缀什么的
//可以设置返回值为空void 或者Object通用,这里我们为了测试采用String返回值
public String parseMethod(Class&?& clazz) throws IllegalArgumentException,
IllegalAccessException, InvocationTargetException,
SecurityException, NoSuchMethodException, InstantiationException {
//获得该对象
Object obj = clazz.getConstructor(new Class[]{}).newInstance(new Object[]{});
//变量该对象的方法
for (Method method : clazz.getDeclaredMethods()) {
//获取方法的注解,
HelloWorldAnnotation say = method.getAnnotation(HelloWorldAnnotation.class);
if (say != null) {
//这里我们先前定义了
UseHelloWorld.sayHello(String name)方法
//这里可以从注解中获取值,或者直接运行,或者缓存该对象方法
String name = say.name();
return (String)method.invoke(obj, name);
return "";
PHP开发框架
开发工具/编程工具
服务器环境
ThinkSAAS商业授权:
ThinkSAAS为用户提供有偿个性定制开发服务
ThinkSAAS将为商业授权用户提供二次开发指导和技术支持
让ThinkSAAS更好,把建议拿来。
开发客服微信关注51Testing
Java注解annotation用法和自定义注解处理器
发表于: 10:07 &作者:zhao_xiao_long & 来源:51Testing软件测试网采编
推荐标签:
  实体使用注解:这里是运用了运行时候处理注解,所以RetentionPolicy.RUNTIME
package whut.annotationDB; @DBTable(name="MEMBER") public class Member { &&& //在使用注解过程中,如果有元素是value,并且只有value需要赋值, &&& //则只需要在()中将值写入 &&& @SQLString(30) &&& private String firstN &&& @SQLString(50) &&& private String lastN &&& @SQLInteger&&& private I &&& @SQLString(value=30,constraints=@Constraints(primaryKey=true)) &&& private S &&& public String getFirstName() { &&&&&&& return firstN &&& } &&& public void setFirstName(String firstName) { &&&&&&& this.firstName = firstN &&& } &&& public String getLastName() { &&&&&&& return lastN &&& } &&& public void setLastName(String lastName) { &&&&&&& this.lastName = lastN &&& } &&& public Integer getAge() { &&&&&&& &&& } &&& public void setAge(Integer age) { &&&&&&& this.age = &&& } &&& public String getHandle() { &&&&&&& &&& } &&& public void setHandle(String handle) { &&&&&&& this.handle = &&& } }
  具体的非apt实现的注解处理器:
package whut.annotationDB; import java.lang.annotation.A import java.lang.reflect.F import java.sql.C import java.sql.DriverM import java.sql.PreparedS import java.sql.SQLE import java.util.ArrayL import java.util.L public class TableCreator { &&& public Connection getConnection() { &&&&&&& String user = "root"; &&&&&&& String password = ""; &&&&&&& String serverUrl = "jdbc:mysql://localhost:3306/carrent?user=root&password="; &&&&&&& try { &&&&&&&&&&& Class.forName("com.mysql.jdbc.Driver"); &&&&&&&&&&& Connection con = DriverManager.getConnection(serverUrl, user, &&&&&&&&&&&&&&&&&&& password); &&&&&&&&&&& &&&&&&& } catch (Exception e) { &&&&&&&&&&& e.printStackTrace(); &&&&&&&&&&& &&&&&&& } &&& } &&& //实现创建表 &&& public static void main(String[] args) { &&&&&&& TableCreator tc = new TableCreator(); &&&&&&& tc.executeCreateDB(Member.class); &&& } &&& public void executeCreateDB(Class&?& entity) { &&&&&&& String sqlStr = explainAnnotation(entity); &&&&&&& Connection con = getConnection(); &&&&&&& PreparedStatement psql = &&&&&&& if (con != null && !sqlStr.equals("error")) { &&&&&&&&&&& try { &&&&&&&&&&&&&&& psql = con.prepareStatement(sqlStr); &&&&&&&&&&&&&&& psql.execute(); &&&&&&&&&&& } catch (SQLException e) { &&&&&&&&&&&&&&& e.printStackTrace(); &&&&&&&&&&& } catch (Exception e) { &&&&&&&&&&&&&&& e.printStackTrace(); &&&&&&&&&&& } finally { &&&&&&&&&&&&&&& try { &&&&&&&&&&&&&&&&&&& if (psql != null) &&&&&&&&&&&&&&&&&&&&&&& psql.close(); &&&&&&&&&&&&&&& } catch (SQLException e) { &&&&&&&&&&&&&&&&&&& e.printStackTrace(); &&&&&&&&&&&&&&& } &&&&&&&&&&&&&&& try { &&&&&&&&&&&&&&&&&&& if (con != null) &&&&&&&&&&&&&&&&&&&&&&& psql.close(); &&&&&&&&&&&&&&& } catch (SQLException e) { &&&&&&&&&&&&&&&&&&& e.printStackTrace(); &&&&&&&&&&&&&&& } &&&&&&&&&&& } &&&&&&& } else&&&&&&&&&&& System.out.println("failure to..."); &&& } &&& // 真正的处理器,Class&?&必须用这个表明 &&& public String explainAnnotation(Class&?& entity) { &&&&&&& // 获取指定类型的注解 &&&&&&& DBTable dbtable = entity.getAnnotation(DBTable.class); &&&&&&& if (dbtable == null) { &&&&&&&&&&& System.out.println("No DBTable annotation in class"&&&&&&&&&&&&&&&&&&& + entity.getName()); &&&&&&&&&&& return "error"; &&&&&&& } else { &&&&&&&&&&& String tableName = dbtable.name();// 获取注解name值,即表名称 &&&&&&&&&&& // 当没有设置name值,直接利用类的名作为表名 &&&&&&&&&&& if (tableName.length() & 1) &&&&&&&&&&&&&&& tableName = entity.getName().toUpperCase();// 转换大写 &&&&&&&&&&& // 准备处理字段注解 &&&&&&&&&&& List&String& columnsDefs = new ArrayList&String&(); &&&&&&&&&&& // 获取该类的所有字段 &&&&&&&&&&& for (Field field : entity.getDeclaredFields()) { &&&&&&&&&&&&&&& String columnName = &&&&&&&&&&&&&&& // 获取该字段所有的注解 &&&&&&&&&&&&&&& Annotation[] anns = field.getDeclaredAnnotations(); &&&&&&&&&&&&&&& // Annotation[] anns=field.getAnnotations(); &&&&&&&&&&&&&&& // 当有注解的时候 &&&&&&&&&&&&&&& if (anns.length &= 1) { &&&&&&&&&&&&&&&&&&& // 判断注解的类型 &&&&&&&&&&&&&&&&&&& if (anns[0] instanceof SQLInteger) { &&&&&&&&&&&&&&&&&&&&&&& SQLInteger sInt = (SQLInteger) anns[0]; &&&&&&&&&&&&&&&&&&&&&&& // 当没有name时候,将字段大写为列名 &&&&&&&&&&&&&&&&&&&&&&& if (sInt.name().length() & 1) &&&&&&&&&&&&&&&&&&&&&&&&&&& columnName = field.getName().toUpperCase(); &&&&&&&&&&&&&&&&&&&&&&& else&&&&&&&&&&&&&&&&&&&&&&&&&&& columnName = sInt.name(); &&&&&&&&&&&&&&&&&&&&&&& columnsDefs.add(columnName + " INT"&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& + getConstraints(sInt.constraints())); &&&&&&&&&&&&&&&&&&& } &&&&&&&&&&&&&&&&&&& if (anns[0] instanceof SQLString) { &&&&&&&&&&&&&&&&&&&&&&& SQLString sString = (SQLString) anns[0]; &&&&&&&&&&&&&&&&&&&&&&& // 当没有name时候,将字段大写为列名 &&&&&&&&&&&&&&&&&&&&&&& if (sString.name().length() & 1) &&&&&&&&&&&&&&&&&&&&&&&&&&& columnName = field.getName().toUpperCase(); &&&&&&&&&&&&&&&&&&&&&&& else&&&&&&&&&&&&&&&&&&&&&&&&&&& columnName = sString.name(); &&&&&&&&&&&&&&&&&&&&&&& columnsDefs.add(columnName + " VARCHAR("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& + sString.value() + ")"&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& + getConstraints(sString.constraints())); &&&&&&&&&&&&&&&&&&& } &&&&&&&&&&&&&&& } &&&&&&&&&&& } &&&&&&&&&&& StringBuilder createDB = new StringBuilder("CREATE TABLE "&&&&&&&&&&&&&&&&&&& + tableName + "("); &&&&&&&&&&& for (String cols : columnsDefs) &&&&&&&&&&&&&&& createDB.append(" " + cols + ","); &&&&&&&&&&& // 移除最后一个,号 &&&&&&&&&&& String tableSQL = createDB.substring(0, createDB.length() - 1) &&&&&&&&&&&&&&&&&&& + ");"; &&&&&&&&&&& // 输出创建表的过程 &&&&&&&&&&& System.out.println("Table Creation SQL is:\n" + tableSQL); &&&&&&&&&&& return tableSQL; &&&&&&& } &&& } &&& // 返回指定的约束 &&& public String getConstraints(Constraints con) { &&&&&&& String constras = ""; &&&&&&& if (!con.allowNull()) &&&&&&&&&&& constras += " NOT NULL"; &&&&&&& if (con.primaryKey()) &&&&&&&&&&& constras += " PRIMARY KEY"; &&&&&&& if (con.unique()) &&&&&&&&&&& constras += " UNIQUE"; &&&&&&& &&& } }
公益活动:
搜索风云榜
51Testing官方微信
51Testing官方微博
测试知识全知道深入理解Java:注解(Annotation)自;要深入学习注解,我们就必须能定义自己的注解,并使;元注解:;元注解的作用就是负责注解其他注解;1.@Target,;2.@Retention,;3.@Documented,;4.@Inherited;这些类型和它们所支持的类在java.lang.a;@Target:;@Target说明了Annotation所
深入理解Java:注解(Annotation)自定义注解入门
要深入学习注解,我们就必须能定义自己的注解,并使用注解,在定义自己的注解之前,我们就必须要了解Java为我们提供的元注解和相关定义注解的语法。
元注解的作用就是负责注解其他注解。Java5.0定义了4个标准的meta-annotation类型,它们被用来提供对其它 annotation类型作说明。Java5.0定义的元注解:
1.@Target,
2.@Retention,
3.@Documented,
4.@Inherited
这些类型和它们所支持的类在java.lang.annotation包中可以找到。下面我们看一下每个元注解的作用和相应分参数的使用说明。
@Target说明了Annotation所修饰的对象范围:Annotation可被用于 packages、types(类、接口、枚举、Annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数)。在Annotation类型的声明中使用了target可更加明晰其修饰的目标。
作用:用于描述注解的使用范围(即:被描述的注解可以用在什么地方)
取值(ElementType)有:
1.CONSTRUCTOR:用于描述构造器
2.FIELD:用于描述域
3.LOCAL_VARIABLE:用于描述局部变量
4.METHOD:用于描述方法
5.PACKAGE:用于描述包
6.PARAMETER:用于描述参数
7.TYPE:用于描述类、接口(包括注解类型) 或enum声明
使用实例:
@Target(ElementType.TYPE)
public @interface Table {
* 数据表名称注解,默认值为类名称
public String tableName() default &className&;
@Target(ElementType.FIELD)
public @interface NoDBColumn {
注解Table 可以用于注解类、接口(包括注解类型) 或enum声明,而注解NoDBColumn仅可用于注解类的成员变量。
@Retention:
@Retention定义了该Annotation被保留的时间长短:某些Annotation仅出现在源代码中,而被编译器丢弃;而另一些却被编译在class文件中;编译在class文件中的Annotation可能会被虚拟机忽略,而另一些在class被装载时将被读取(请注意并不影响class的执行,因为Annotation与class在使用上是被分离的)。使用这个meta-Annotation可以对 Annotation的“生命周期”限制。
作用:表示需要在什么级别保存该注释信息,用于描述注解的生命周期(即:被描述的注解在什么范围内有效)
取值(RetentionPoicy)有:
1.SOURCE:在源文件中有效(即源文件保留)
2.CLASS:在class文件中有效(即class保留)
3.RUNTIME:在运行时有效(即运行时保留)
Retention meta-annotation类型有唯一的value作为成员,它的取值来自
java.lang.annotation.RetentionPolicy的枚举类型值。具体实例如下:
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
public String name() default &fieldName&;
public String setFuncName() default &setField&;
public String getFuncName() default &getField&;
public boolean defaultDBValue()
Column注解的的RetentionPolicy的属性值是RUTIME,这样注解处理器可以通过反射,获取到该注解的属性值,从而去做一些运行时的逻辑处理
@Documented:
@Documented用于描述其它类型的annotation应该被作为被标注的程序成员的公共API,因此可以被例如javadoc此类的工具文档化。Documented是一个标记注解,没有成员。
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Column {
public String name() default &fieldName&;
public String setFuncName() default &setField&;
public String getFuncName() default &getField&;
public boolean defaultDBValue()
@Inherited:
@Inherited 元注解是一个标记注解,@Inherited阐述了某个被标注的类型是被继承的。如果一个使用了@Inherited修饰的
annotation类型被用于一个class,则这个annotation将被用于该class的子类。
注意:@Inherited annotation类型是被标注过的class的子类所继承。类并不从它所实现的接口继承annotation,方法并不从它所重载的方法继承annotation。
当@Inherited annotation类型标注的annotation的Retention是
RetentionPolicy.RUNTIME,则反射API增强了这种继承性。如果我们使用java.lang.reflect去查询一个@Inherited annotation类型的annotation时,反射代码检查将展开工作:检查class和其父类,直到发现指定的annotation类型被发现,或者到达类继承结构的顶层。
实例代码:
* @author peida
@Inherited
public @interface Greeting {
public enum FontColor{ BULE,RED,GREEN};
String name();
FontColor fontColor() default FontColor.GREEN;
自定义注解:
使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口,由编译程序自动完成其他细节。在定义注解时,不能继承其他的注解或接口。@interface用来声明一个注解,其中的每一个方法实际上是声明了一个配置参数。方法的名称就是参数的名称,返回值类型就是参数的类型(返回值类型只能是基本类型、Class、String、enum)。可以通过default来声明参数的默认值。
定义注解格式:
public @interface 注解名 {定义体}
注解参数的可支持数据类型:
1.所有基本数据类型(int,float,boolean,byte,double,char,long,short)
2.String类型
3.Class类型
4.enum类型
5.Annotation类型
6.以上所有类型的数组
Annotation类型里面的参数该怎么设定:
第一,只能用public或默认(default)这两个访问权修饰.例如,String value();这里把方法设为defaul默认类型;
第二,参数成员只能用基本类型byte,short,char,int,long,float,double,boolean八种基本数据类型和 String,Enum,Class,annotations等数据类型,以及这一些类型的数组.例如,String value();这里的参数成员就为S
第三,如果只有一个参数成员,最好把参数名称设为&value&,后加小括号.例:下面的例子FruitName注解就只有一个参数成员。
简单的自定义注解和使用注解实例:
import java.lang.annotation.D
import java.lang.annotation.ElementT
import java.lang.annotation.R
import java.lang.annotation.RetentionP
import java.lang.annotation.T
* 水果名称注解
* @author peida
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitName {
String value() default &&;
import java.lang.annotation.D import java.lang.annotation.ElementT import java.lang.annotation.R
import java.lang.annotation.RetentionP import java.lang.annotation.T
* 水果颜色注解
* @author peida
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME) @Documented
public @interface FruitColor {
* 颜色枚举
* @author peida
public enum Color{ BULE,RED,GREEN};
* 颜色属性
Color fruitColor() default Color.GREEN;
import annotation.FruitColor.C
public class Apple {
@FruitName(&Apple&)
包含各类专业文献、行业资料、生活休闲娱乐、应用写作文书、高等教育、各类资格考试、外语学习资料、幼儿教育、小学教育、深入理解Java:注解(Annotation)自定义注解入门30等内容。 
 深入理解Java:注解(Annotation)自定义注解入门_计算机软件及应用_IT/计算机_专业资料。Java 中注解(Annotation)自定义注解入门 要深化学习注解,咱们就必须能界说自个...  深入理解 Java:注解(Annotation)自定义注解入门要深入学习注解,我们就必须能定义自己的注解,并使用注解,在定义自己的注解之前,我们就必须 要了解 Java 为我们提供的...  java自定义注解_计算机软件及应用_IT/计算机_专业资料。java 注解是附加在代码中...(ElementType.ANNOTATION_TYPE) public @interface Target { ElementType[] value...  (RenderMethod)method.getAnnotation(RenderMethod....《java 编程思想》 2. 《深入理解 java 虚拟机》...利用自定义Java注解实现... 9页 免费 Java基础复习...  利用自定义 Java 注解实现资源注入这里是想介绍一下...(type=&B&, sqlMap=&com/annotation/sql-map-...Java注解 8页 免费 Java基础复习笔记12Java... 8...  父类,接口 Java.lang.annotation 包 java.lang.annotation 中包含所有已定义或自定义注解所需用到的原注解和接口。如接口 java.lang.annotation.Annotation 是所有...  深入理解 Java:注解(Annotation)自定义注解入门要深入学习注解,我们就必须能定义自己的注解,并使用注解,在定义自己的注解之前,我 们就必须要了解 Java 为我们提供...  照片是数据, 他拍摄的时间就是元数据) java注解:也就是Annotation,是java代码...自定义注解 2:根据是否有成员变量注解又分为: ①:标记注解:没有定义成员变量的...Java基础复习笔记12Java自定义注解Annotation的使用 - 琉璃仙境 - ITeye技术网站
博客分类:
自JDK1.5以后,推出了注解新特性。注解的推出其实最主要的目的是为了让广大的用户认知EJB3.0,因为EJB2.X广受大多数开发者的诟骂和质疑。为了减少配置、让注解替代配置。有了注解,我们以前看似一般的、普通的JavaBean就有了活力,有了内涵,有了新的契机。配合Sun的JPA规范,EJB3.X又再次在企业级开发中大放异彩,让很多开发者赞不绝口。也许是无心插柳,这种“零配置”思维也影响着Java其他的开源项目——像Struts、Spring、Hibernate(也就是咱们耳熟能详的SSH)不都是具有“零配置”支持嘛!Java现在也是往动态、敏捷的方向发展着。有可能将来配置文件越来越少、规范、约定、注解代替了繁琐的配置信息。而XML估计会回归原始的使命——数据传输与数据交换。
自定义注解
至于已有的注解,比如:JPA、EJB、Spring零配置等等怎么使用相信各位读者都能掌握,这里主要是说如何自定义自己的注解,自己使用自定义的注解。
我们先用一个简单的例子来看
import java.lang.annotation.R
import java.lang.annotation.RetentionP
* @author Administrator
@Retention(RetentionPolicy.RUNTIME)
public @interface Test {
String isAop() default "false";
用关键字@interface定义一个注解标记,使用@interface关键字实际上的意思就是该接口继承自java.lang.annotation.Annotation接口。
String isAop() default "false";
这句话代表的意思就是在Test注解中可以含有属性名为isAop,此属性的类型是字符串类型。客户端使用的时候可以根据需要自己指定相关的属性值。如果客户端不指定值,默认值是false
@Retention(RetentionPolicy.RUNTIME)
import annotation.T
import annotation.TestImpl.TestP
@Test(isAop = "true")
public class UseTest {
* @param args
* @throws ClassNotFoundException
public static void main(String[] args) throws ClassNotFoundException {
TestProcess.process("use.UseTest");
在客户端调用中在类UseTest上使用了@Test(isAop = "true")注解。仅仅定义了注解就像《三国杀》里,刘备是主公,他有“激将”的主公计,下了个命令:“蜀将何在?”,刘备的这句话太抽象了,蜀将相当于一个注解。在场的所有蜀将就像加了此注解的类,都会受到这句话的影响。具体替不替刘备出杀,~~~~个人表现不同(得先看看自己的身份啊)反贼的表现是:“这个真没有”;忠臣的表现是,先看看手上有杀吗?有,出击吧!没有就说:“这个……真没有!”;内奸的反应是:“唉,先保命还是装一装忠臣?比较纠结!”。这里的身份就好像是注解的属性的不同值。具体的处理就相当于针对注解的处理实现类。注解的具体实现类就是处理注解的业务逻辑,它需要Java的反射机制来处理客户目标类的具体注解,我们就来看看这个注解处理实现类。
package annotation.TestI
import java.lang.annotation.A
public class TestProcess {
public static void process(String str) throws ClassNotFoundException {
Class clazz = Class.forName(str);
Annotation[] annotations = clazz.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println(annotation);
以上的处理逻辑很简单,就是根据一个字符串类名找到类。获得类的所有注解,所有注解是一个对象数组。遍历注解数组,输出相关注解信息。运行以上的程序结果如下
@annotation.Test(isAop=true)
如果我们使用注解的客户端代码替换一下
public class UseTest {
……………………
对于注解的isAop并不特别指定。运行效果如下
@annotation.Test(isAop=false)
可以看到使用的是默认值false。如果注解中Annotation并没有指定默认值,而在客户端使用中也没指定值,那么不会通过编译。 @Retention(RetentionPolicy.XXXXXX)上面说到了是保留注解的有效期。
//会将注解保留到编译后的class中,加载类的时候不生效
@Retention(RetentionPolicy.CLASS)
//仅仅在代码保留,编译后的class不会保留
@Retention(RetentionPolicy.SOURCE)
//在编译后的class会有,通过反射也会获得注解信息
@Retention(RetentionPolicy.RUNTIME)
比如Override注解的源码
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
因为复写在使用者使用的时候就可以看出来,所以没必要保留到运行期。
比如SuppressWarnings注解的源码
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
String[] value();
以上的不提示警告的注解也是在编译一个类前检查即可。
以上还使用了@Target注解,它代表着注解的修饰范围,类型是java.lang.annotation.ElementType枚举类型。
public enum ElementType {
TYPE,//可以修饰类、接口、枚举、注解
FIELD,//可以修饰成员变量
METHOD,//可以修饰方法
PARAMETER,//可以修饰参数
CONSTRUCTOR,//可以修饰构造方法
LOCAL_VARIABLE,//可以修饰局部变量
ANNOTATION_TYPE,// 可以修饰Annotation
PACKAGE//可以修饰包
看Deprecated源码
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface Deprecated {
Deprecated代表已过时的意思,这是一个保持到运行期的注解,在运行期可以通过反射获取此注解。文档中的内容会因为此注解的信息内容不同而不同。
还有一个注解就是Inherited,如果使用了该标记,那么使用该注解的子类也会继承该注解的特性。
很多人有疑问,你说这些有什么用?对于开发有什么促进吗?EJB注解、JPA注解我们会使用完成业务不就得了。下面再来看一个程式例子
import java.lang.annotation.ElementT
import java.lang.annotation.R
import java.lang.annotation.RetentionP
import java.lang.annotation.T
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Pojo {
String table();
import java.lang.annotation.ElementT
import java.lang.annotation.R
import java.lang.annotation.RetentionP
import java.lang.annotation.T
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Colum {
String columName();
boolean isNULL()
String Type() default "";
处理注解的逻辑实现类
package annotation.TestI
import java.lang.annotation.A
import java.lang.reflect.F
import annotation.C
import annotation.P
public class MyJPAProcess {
public static void process(Object object) throws ClassNotFoundException {
// 所有注解
Annotation[] annotationsClass = object.getClass().getAnnotations();
Field[] fields = object.getClass().getDeclaredFields();
// 遍历注解元素
for (Annotation annotation : annotationsClass) {
if (annotation instanceof Pojo) {
System.out.println("--------处理POJO实体--------");
Pojo pojo = (Pojo)
System.out.println("存储表名:" + pojo.table());
for (Field field : fields) {
//field.setAccessible(true);
Annotation[] annotationsMethos = field.getAnnotations();
// 遍历注解元素
for (Annotation annotation : annotationsMethos) {
if (annotation instanceof Colum) {
System.out.println("--------处理Colum字段--------");
Colum colum = (Colum)
System.out.println("字段名:" + colum.columName());
System.out.println("字段类型:" + colum.Type());
System.out.println("是否能为空:" + colum.isNULL());
以上是定义了简单的2个注解Pojo和Colum。之后为这2个注解提供了逻辑处理。下面我们来看看客户端是怎么使用的吧。
一般的实体类
import annotation.C
import annotation.P
@Pojo(table = "person")
public class PersionPOJO {
public PersionPOJO() {
@Colum(columName = "id", isNULL = false, Type = "varchar")
@Colum(columName = "name", isNULL = false, Type = "varchar")
@Colum(columName = "age", isNULL = true, Type = "int")
//省略set/get
这是一个普通的实体对象+自定义的注解。针对于这个POJO我们再定义一个DAO类操作这个POJO类。
import annotation.TestImpl.MyJPAP
public class PersionDAO {
public void save(PersionPOJO persionPOJO) throws ClassNotFoundException {
MyJPAProcess.process(persionPOJO);
public static void main(String[] args) throws ClassNotFoundException {
PersionDAO persionDAO = new PersionDAO();
PersionPOJO persionPOJO = new PersionPOJO();
persionDAO.save(persionPOJO);
上面程序就定义了一个保存方法,测试一下,调用这个save方法。控制台输出如下信息。
--------处理POJO实体--------
存储表名:person
--------处理Colum字段--------
字段名:id
字段类型:varchar
是否能为空:false
--------处理Colum字段--------
字段名:name
字段类型:varchar
是否能为空:false
--------处理Colum字段--------
字段名:age
字段类型:int
是否能为空:true
DAO中调用了注解逻辑实现类的方法。这个时候我们稍微修改一下注解逻辑实现类的方法,配合一个ORM中间件,就可以将数据保存到数据库了。
其实自定义注解一般是公司或者团队觉得一些原有的配置比较麻烦,加上注解是为了减少配置。还有一个目的:自己开发框架,让自己的团队更敏捷、更快速的相应纷繁错杂的客户需求。其实还有一个目的:就是制定规范,JPA是规范、EJB是规范……至于底层对于这些注解规范的实现则因不同的容器决定的。所谓容器就是JBoss或者Weblogic这种JavaEE容器的自己的jar包,像Java SDK也是提出了相应的规范,不同的组织对这个规范的实现也是仁者见仁智者见智,像上面提出的JDK内的注解就是提出了规范,我自己sun有一套实现机制,其他的组织用我sun的JDK实现不爽也可以自行实现这套注解机制。这样通过反射机制获取本应该在配置文件中配置的一些信息。减少了冗余的配置文件。至于效率嘛~~~有人说反射机制比解析配置慢、有人说配置文件要是过长会比反射慢很多。这个笔者觉得仁者见智者见智,没有绝对的答案,到底使用哪个?还是得因环境而异。
/
兄弟!!!你是在做广告吗???这里最好不要做广告
混了些年月,还没有专门针对Java 的注解进行过开发。
不过倒是进行类似这样的功能的编码还是做过:
@Colum(columName = "age", isNULL = true, Type = "int")
那也是在程序生成pojo类代码的情况下,通过数据库获取到表字段信息,然后再注释里面进行编排,比较过程化,很显然没有本文讨论的注解那么强大!
又一次扫盲了.....功在千秋哦
唉~~~说哪里话~~~
suhuanzheng7784877
浏览: 521454 次
来自: 北京
浏览量:42054
可以参考最新的文档:如何在eclipse jee中检出项目并转 ...
看完我就去厕所思考了~~写的太好了~~
夫处世之道,亦即应变之术,岂可偏执一端? 用兵之道,亦然如此, ...
不应该 delete 执着;应该有原则的 执着if(天时||地 ...
我想请问楼主 怎么样才能通过memcache客户端在程序中通过 ...

我要回帖

更多关于 hadoop伪分布式模式 的文章

 

随机推荐