为了是大家初步了解什么是注解(Annotation),我们先来看如下代码:
相关代码一:
public class
AnnotationTest {
public static void main(String[] args) {
Date nowDate
= new Date();
String strDate = nowDate.toLocaleString();
System.out.println(strDate);// 2009-12-27
16:44:09
}
}
上述代码在eclipse编辑器中会出现警告,内容为"The method toLocaleString() from
the type Date is
deprecated",它的意思是说toLocaleString()方法是个过时的方法;
为了更好的理解它的含义,我们在cmd窗口来编译它,如下
那么我们可以怎么把这个警告给去掉呢,这是就要使用到注解,我们在main方法之前加上这样一句"@SuppressWarnings("deprecation")",也可以用快捷方式加上,那么警告就会消失。
代码就变成了这样:
public
class AnnotationTest {
@SuppressWarnings("deprecation")
public static void
main(String[] args) {
Date nowDate = new Date();
String strDate =
nowDate.toLocaleString();
System.out.println(strDate);// 2009-12-27
16:44:09
}
}
注意:每个注解就是一个类,我们在用注解时,就相当于创建了一个注解类的实例;
2.在写程序中,我们可能不希望某个方法之后不被再次调用,那么我们就可以把这个方法定义为过时的方法,过时的方法在调用时,会在方法名上打上删除线,告诉程序员该方法为过时方法,最后不要再用了。下面我们写一个自定义的过时方法:
相关代码二:
public
class AnnotationTest {
@Deprecated
private static void
sayHello() {
System.out.println("Hello word !");
}
public static
void main(String[] args) {
AnnotationTest.sayHello();
}
}
注意:只需要在方法前加上:@Deprecated,那么该方法就会被eclipse编辑器打上删除线,来表明为过时方法.
3.JDK为我们提供了如下3中基本的注解Annotation:
.Deprecated:用@Deprecated
注释的程序元素,不鼓励程序员使用这样的元素,通常是因为它很危险或存在更好的选择。
.Override:用@Override表示一个方法声明打算重写超类中的另一个方法声明。
.SuppressWarnings:@SuppressWarnings("deprecation")指示应该在注释元素(以及包含在该注释元素中的所有程序元素)中取消显示指定的编译器警告。
4.注解相当于一种标记,在程序中加了注解就等于为程序打上了某种标记,没加,则等于没有某种标记,以后,java编译器,开发工具和其他程序可以用反射来了解你的类及各种元素上有无何种标记,看你有什么标记,就去干相应的事,标记可以加在包,类,字段,方法,方法的参数以及局部变量上。它位于java.lang.annotation中。
5.通常应用注解有如下三个步骤:
1).定义注解类,格式为:public
@interface A{
}
2).应用注解类,如:
@A
class
B{
}
3).对应用注解类的类进行反射操作(的类),如:
B.class.isAnnotationPresent(A.class);
A
a = B.class.isAnnotationPresent(A.class);
6.下面我们来完成上述三步操作:
1).切换到java透视图上,点击新建一个注解:
代码如:
public
@interface MyAnnotation {
}
2).创建一个类应用该注解:
@MyAnnotation
public
class AnnotationTest {
public static void main(String[] args)
{
}
}
3.对应用注解类的类进行反射操作:
public static void main(String[] args)
{
if (AnnotationTest.class.isAnnotationPresent(MyAnnotation.class))
{
MyAnnotation myAnnotation =
AnnotationTest.class.getAnnotation(MyAnnotation.class);
System.out.println(myAnnotation);
}
}
注:这是程序运行没有输出,明明有注解,怎么会没输出呢?这时我们在MyAnnotation注解类前面加上:@Retention(RetentionPolicy.RUNTIME),再次运行时,就会输出"MyAnnotation"
7.下面我们来解释下什么叫Retention,Retention本身也是一个注解,叫元注解,它后面跟一个值,这个值表示该注解保留到代码的那个阶段;
@Retention元注解,有三种取值,即有三种生命周期:
RetentionPolicy.SOURCE:对应java源文件
RetentionPolicy.CLASS:对应class文件
RetentionPolicy.RUNTIME:对应内存中的字节码
默然值就是RetentionPolicy.CLASS,在注解类上加的注解叫“元注解”,class文件本身不是字节码,只有class文件被类加载器被加载到内存中进行校检处理之后,才是二进制的字节码,他们的生命周期不是不同的。
注:如果我们把6中的RetentionPolicy.RUNTIME,改成其他两个中任何一个得话,也是无输出的,因外其他两个的注解生命周期不是运行期,即在内存中无法找到。
8.如果我们在MyAnnotation注解类前面再加上:@Target(ElementType.METHOD),那么AnnotationTest类前面就会有错误提示:"The annotation @MyAnnotation is disallowed for this location",即@MyAnnotation不能放在这个位置,为什么呢?因为刚才我们在MyAnnotation注解类前面再加上:@Target(ElementType.METHOD),它表示该注解只能用在方法上面,如果要想让该注解用的类上面,就可以不刚才那句修改成"@Target({ElementType.METHOD,ElementType.TYPE})",ElementType.TYPE它表示该注解可以应用的类,接口,枚举等类型上。
9.注解的高级应用-为注解增加属性,我们在刚才的MyAnnotation注解类增加一个属性,代码如下:
代码:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
public
@interface MyAnnotation {
String
color();
}
那么此时,我们就会发现,AnnotationTest类的上面有错误提示“The annotation
@MyAnnotation must define the attribute
color”,即必定义color的属性,我们此时就可以把类上面的注解修改成:@MyAnnotation(color="red"),OK了!说明注解类有属性时,在我们调用时就必须提供属性值,除非注解类中的属性有默认值,
代码:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
public
@interface MyAnnotation {
String color() default
"yellow";
}
调用的时候就可以直接:@MyAnnotation或@MyAnnotation();
再如代码:
public @interface MyAnnotation
{
String color() default "yellow";
String style();
}
调用的时候就可以直接:
@MyAnnotation(color="red",)或@MyAnnotation();有默认值的时候,默认值可以省略。
但是通常我们有如下用法:
@SuppressWarnings("deprecation"),它怎么只提供属性值,而没有属性名呢?这就是value()属性的特殊用法,它可以放回任意类型;
再如代码:
public @interface MyAnnotation
{
String color() default "yellow";
String style() default
"fashion";
String value();
}
调用的时候就可以直接:
@MyAnnotation(color="red",,value="hello")
或@MyAnnotation("hello");
10.为注解增加高级属性,如数组,枚举,注解,具体就不再举例了,可以参考java语言规范中的实例。
转自:http://hi.baidu.com/suny_duan/blog/item/25a1c8ae3ed763f0faed50ec.html
一个array(数组)就像是把一套变量组织在一起的容器。单个数组可以含有许多不同的值。你可以储存和取得数组中的单个值(也就是数组elements(元素))。你也可以通过直接操作数组变量来成组地使用其值。最常见的是有序数组。你可以凭某个索引号从中获取值。Action Script3包括了用于索引数组的两个类。
- Array 类:一个可以包含各种值类型的索引数组,其包容度甚至可以允许你在同一个数组里混合各种值类型。
- Vector类:也是索引数组。其元素必须都为同一个类的实例。Vector类适用于 Flash Player 10和之后的版本。
如果你需要存储一系列具有相同数据类型的值,与Array类相比,Vector类有一些优势。首先,因为Vector的所有元素要求必须有相同的数据类型,所以ActionScript编译器在代码编译的时候就可以进行类型检查。任意尝试添加或恢复错误类型值的代码都将被处理为编译时错误。数据类型在运行时也会进行检查,因此,假设数据类型不能再编译时被检查出来,它仍然会被检查,而且数据类型限制也还是有效的。除了类型检查的优点之外,使用Vector类的代码比使用Array创建的同样代码明显运行得要快— —这是一个重要的优势。
这篇快速入门描述了创建于使用Vector类的技巧。要了解更多关于Array类的使用,请参考Flash快速入门使用数组编程。
以下段落描述了使用Vector对象的常用接下来的部分描述了用Vector对象完成一般任务:创建一个Vector实例,为一个Vector对象添加值,为一个Vector对象更改值,为一个Vector对象的值分类。
基本要求要实现这篇快速入门中的实例,你需要如下实例文件:
- Flash Professional
- programming_with_vector.zip
这个示例存档文件包含了如下几个文件:
- SortVectorOfNumber.fla:一个Flash文件,演示了在Vector中对数字值进行排序,在本文中的"将一个Vector中的值进行排序"分段中进行描述。
- SortVectorOfObject.fla:一个示例演示中Vector中对常用对象进行排序,在本文中的"将一个Vector中的值进行排序"分段中进行描述。
- Person.as:Person类的源码,在SortVectorOfObject.fla中引用。
要测试每个应用,请打开FLA文件,并选择"控制 > 测试影片"。
预备知识推荐有使用ActionScript3编程的一般经验。
创建一个Vector实例一个Vector对象是一个只保存着某类值的索引数组。Vector对象特定保存的类是Vector的基本型。而调用Vector类的构造函数的时候就创建了一个Vector对象。你也许猜到了,制定给Vector变量的基本类必须匹配调用构造函数时指定的基本型。
当创建一个Vector实例的时候,为了指定它的基本型,你要在Vector类名字上增加额外的信息, 使用一个叫做类型参数的语法格式。比如,下面的表述声明了一个叫做myVector的Vector变量,使用类型参数语法来指出在myVector里的 Vector只能包含字符串类型的值。
var myVector:Vector.<String>;
当你调用Vector构造函数来实际创建Vector对象的时候可以用一样的语法:
myVector = new Vector.<String>();
作为一种规则,只要有Vector这个类名出现在你的代码里,你总是要对它使用一个类型参数。
当然,你可以把变量声明和构造实例整合到一行代码里。
var myVector:Vector.<String> = new Vector.<String>();
尽管在这篇快速入门中所给的示例都比较简单,例如创建String和Number作为Vector的基类型,实际上,Vector类的基类型可以是任何类。这也包括你定义的自定义类。例如,假设你的代码定义了一个名为MyClass的类。在这种情况下,下面的代码是有效的,它将创建一个Vector对象,它的元素都必须是MyClass实例:
var v:Vector.<MyClass> = new Vector.<MyClass>();预设Vector的长度
Vector类构造函数有两个可选参数,它允许你明确你的Vector实例的数量。第一个参数是length参数。默认情况下,当一个Vector被创建时,它是空的(它有0个元素)。然而,如果你传递一个值给length参数,明确元素数量的Vector实例就被创建了:
var myVector:Vector.<String> = new Vector.<String>(7); // myVector is created with 7 elements
预先确定Vector的大小比一次创建一个元素效率要高,所以,如果你提前知道Vector包含有多少元素,提供一个length参数值是比较好的。如果Vector的基类型是一个Boolean或者一个数值类型(Number,int,uint),每个元素都会被赋予这个数据类型的默认值(Boolean的默认值false,数据类型默认值0)。否则,每个元素初始值为null。
创建一个可动态调整长度的VectorVector对象的另一个特征就是他们可以调整长度,这意味着你可以改变值,但是不能通过添加或删除元素来改变总数。默认地,一个Vector实例是不允许动态修改长度的。要创建一个可修改长度的Vector,将Vector类构造函数的第二个参数(fixed参数)设置为true:
var myVector:Vector.<String> = new Vector.<String>(7, true); // myVector's length is fixed to 7 elements
注意: 你可以在任何时候修改Vector对象的fixed属性来设置Vector的长度是否可变。
myVector.fixed = false; // myVector's length is no longer fixed为一个Vector对象添加值
除了一个额外的限制之外,添加一个值到Vector对象中与添加一个值到Array对象中类似。一个Vector对象的每个元素必须有一个值(或者null)。换句话说,你不能在一个序号为4的位置添加一个值,除非Vector的0–3为已经有值了。在实际中,这意味着要添加一个新的元素到Vector中,你必须在等于Vector对象长度的序号位置添加它(因为Vector的第一个元素序号为0,所以length属性的值通常比Vector最后一个元素的序号要大)。下面的代码演示了这一技巧:
var names:Vector.<String> = new Vector.<String>(); // ... assume some elements are added ... // Add an element to the end of the Vector names[names.length] = "Bob";
除了使用array访问符([])操作添加一个值到Vector对象中外,你也可以使用Vector对象的push()或者unshift()方法来添加元素到Vector中。就像Array类一样,push()方法创建了一个新元素在Vector最后一个元素的末尾,unshift()方法创建了一个新元素在Vector序号为0的位置(同时将所有已经存在的元素移位值高一位的位置):
names.push("Harold"); // adds the value "Harold" to the end of the Vector names.unshift("Fred"); // adds the value "Fred" to the start of the Vector
这些方法还有额外的优势是,你可以传递多个值做为参数给方法,所有的值都会一次性添加到Vector对象中。然后,这种弹性的方式也会导致一个后果。当你使用push()或者unshift()方法添加值到Vector对象时,编译器不能检查数据类型是否匹配。因为,任何使用push()或者unshift()添加错误类型的值到Vector对象中的代码知道运行代码时才会被发现。
从Vector对象中恢复值从Vector对象中恢复值与从一个Array对象中恢复值完全一样。要从特定序号位置回复元素值,你需要使用数组访问符([])操作来明确你需要的元素序号:
var name1:String = names[0];
使用数组访问符([])操作恢复值,但是不会将它从Vector对象中移除。要恢复值并且将它从Vector对象中移除,请使用pop()方法(它会移除最后的一个元素)或者shift()方法(它会移除第0个元素,并且所有元素减一位):
var finalName:String = names.pop(); // removes the last value from the Vector var firstName:String = names.shift(); // removes the first value from the Vector将一个Vector中的值进行排序
大部分使用Vector对象的方法与使用Array对象的方法都一样。有一个方法你需要知道的不一样的是在Vector对象元素排序。Vector类仅有一个方法给值排序:sort()方法。sort()方法不会更改原始的Vector对象。取而代之,它返回具有相同基类型包含已排序了值的一个新的Vector。
当你使用Vector类的sort()方法时,它没有默认的排序行为,即使是基本的数据类型如Number或者String。正因为如此,任何时候你使用sort()方法,你都需要指明一个自定义的排序函数来定义排序逻辑。例如,下面的代码中,一个Number类型的Vector对象使用sort()方法来排序。在这个案例中,这个代码演示了基本的数据排序;小的数字放在大的数字前面(升序排列)。名为sortNumbers()的函数定义了排序行为,它做为一个参数传递给了sort()方法调用。Flash Player给每个数字排序时,它调用sortNumber()函数,将要进行比较的两个数值传递给函数,结果决定最终排序的顺序:
var numberVector:Vector.<Number> = new Vector.<Number>(); numberVector.push(2, 17, 3.6, 4.4, 29, -34, 0.09235); trace(numberVector); // output: 2,17,3.6,4.4,29,-34,0.09235 var sortedVector:Vector.<Number> = numberVector.sort(sortNumbers); trace(sortedVector); // output: -34,0.09235,2,3.6,4.4,17,29 function sortNumbers(x:Number, y:Number):Number { if (x < y) { return -1; } else if (x > y) { return 1; } else { return 0; } }
你可以定义为任意数据类型定义一个排序函数。例如,下面的代码为Vector的Person对象根据姓氏(last name)进行了排序,然后是名字(first name)(它假定了有一个Person类具有firstName和lastName属性):
var personVector:Vector.<Person> = new Vector.<Person>(); personVector[0] = new Person("Bob", "Smith"); personVector[1] = new Person("Harold", "Johnson"); personVector[2] = new Person("Barbara", "Smith"); personVector[3] = new Person("Arnold", "Anderson"); personVector[4] = new Person("Margaret", "Wooster"); // output:[Smith,Bob],[Johnson,Harold],[Smith,Barbara],[Anderson,Arnold],[Wooster,Margaret] trace(personVector); var sortedVector:Vector.<Person> = personVector.sort(sortPeople); // output:[Anderson,Arnold],[Johnson,Harold],[Smith,Barbara],[Smith,Bob],[Wooster,Margaret] trace(sortedVector); function sortPeople(x:Person, y:Person):Number { // sort by last name var lastNameSort:Number = sortStrings(x.lastName, y.lastName); if (lastNameSort != 0) { return lastNameSort; } else { // if the last names are identical, sort by first name return sortStrings(x.firstName, y.firstName); } } function sortStrings(x:String, y:String):Number { if (x < y) { return -1; } else if (x > y) { return 1; } else { return 0; } }
<script type="text/javascript"></script>
从项目开发过程中,对Three20 有了更深的了解. 要想写出优质的代码,不仅只是表面.还需更深一步对设计模式的理解.