現(xiàn)在準(zhǔn)備研究1些源碼或框架,但是1些基礎(chǔ)的知識(shí)1定要懂,不然沒(méi)法看,比如設(shè)計(jì)模式,java基礎(chǔ)中的反射,泛型,注解,多線程,線程池,隊(duì)列等,現(xiàn)在很多框架都是這些知識(shí)雜糅而成的,
我們經(jīng)常使用的java內(nèi)置3大注解:
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } }
上面onCreate()方法上@Override就是注解,我們點(diǎn)擊進(jìn)去看看,
package java.lang; import java.lang.annotation.*; /** * Indicates that a method declaration is intended to override a * method declaration in a supertype. If a method is annotated with * this annotation type compilers are required to generate an error * message unless at least one of the following conditions hold: * * <ul><li> * The method does override or implement a method declared in a * supertype. * </li><li> * The method has a signature that is override-equivalent to that of * any public method declared in {@linkplain Object}. * </li></ul> * * @author Peter von der Ahé * @author Joshua Bloch * @jls 9.6.1.4 Override * @since 1.5 */ @Target(ElementType.METHOD) @Retention(RetentionPolicy.SOURCE) public @interface Override { }
@interface就是表明聲明1個(gè)注解類,在java.lang包下,發(fā)現(xiàn)聲明的注解Override上面有2個(gè)@Target和@Retention這2個(gè)注解,
@Target(ElementType.METHOD) 表示注解類(Override)使用再方法上
@Retention(RetentionPolicy.SOURCE) 表示使用再源碼中
@Target說(shuō)明了Annotation所修飾的對(duì)象范圍
再點(diǎn)擊Target進(jìn)去看看:
@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Target { ElementType[] value(); }我們發(fā)現(xiàn)
@Target(ElementType.ANNOTATION_TYPE)
()這個(gè)括號(hào)里的是啥東西呢,還是點(diǎn)擊進(jìn)去看看源碼:
public enum ElementType { /** Class, interface (including annotation type), or enum declaration */ TYPE, /** Field declaration (includes enum constants) */ FIELD, /** Method declaration */ METHOD, /** Formal parameter declaration */ PARAMETER, /** Constructor declaration */ CONSTRUCTOR, /** Local variable declaration */ LOCAL_VARIABLE, /** Annotation type declaration */ ANNOTATION_TYPE, /** Package declaration */ PACKAGE, /** * Type parameter declaration * * @since 1.8 * @hide 1.8 */ TYPE_PARAMETER, /** * Use of a type * * @since 1.8 * @hide 1.8 */ TYPE_USE }這是JDK1.5后出來(lái)的,也就是說(shuō)1.5之前是沒(méi)注解的,ElementType 這是1個(gè)枚舉類,這個(gè)枚舉類中定義了10個(gè)變量,哪這10個(gè)變量都是啥意思呢?
@Target(ElementType.TYPE) //接口、類、枚舉、注解
@Target(ElementType.FIELD) //字段、枚舉的常量
@Target(ElementType.METHOD) //方法
@Target(ElementType.PARAMETER) //方法參數(shù)
@Target(ElementType.CONSTRUCTOR) //構(gòu)造函數(shù)
@Target(ElementType.LOCAL_VARIABLE)//局部變量
@Target(ElementType.ANNOTATION_TYPE)//注解
@Target(ElementType.PACKAGE) ///包
Target注解類中還有1個(gè)聲明注解
@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Retention { RetentionPolicy value(); }
public enum RetentionPolicy { /** * Annotations are to be discarded by the compiler. */ SOURCE, /** * Annotations are to be recorded in the class file by the compiler * but need not be retained by the VM at run time. This is the default * behavior. */ CLASS, /** * Annotations are to be recorded in the class file by the compiler and * retained by the VM at run time, so they may be read reflectively. * * @see java.lang.reflect.AnnotatedElement */ RUNTIME }
源碼中RetentionPolicy 也是1個(gè)枚舉類,定義了3個(gè)變量
java內(nèi)置3大注解:
1:@Override
定義在java.lang.Override中,此注解只適應(yīng)于修飾方法,表示1個(gè)方法聲明打算重寫超類(父類)的另外一個(gè)方法聲明
package com.annotation; /** * Created by admin on 2017/1/10. */ public interface Person { String getName(); int getAge(); void sing(); }這是我們自己寫的1個(gè)接口,
package com.annotation; /** * Created by admin on 2017/1/10. */ public class Child implements Person { @Override public String getName() { return null; } @Override public int getAge() { return 0; } @Override public void sing() { } }我們發(fā)現(xiàn)Child實(shí)現(xiàn)了Person接口,getName(),getAge(),sing()方法上都有@Override注解,表明這3個(gè)方法都是來(lái)自接口Person
2:@Deprecated
定義在java.lang.Deprecated中,此注解可修飾類,方法,屬性,表示不建議程序員使用這個(gè)方法,屬性,類等,表示它已過(guò)時(shí),有更好的選擇或存在危險(xiǎn),下面我是我平時(shí)開發(fā)中很常見(jiàn)的過(guò)時(shí)正告:
3:@SuppressWarnings中,用來(lái)擬制編譯時(shí)正告信息,下面的代碼也是很常見(jiàn)的
哪怎樣修復(fù)呢?有2種,1種是依照提示去補(bǔ)充代碼,比如List要添加泛型,表示這個(gè)list存儲(chǔ)的是甚么類型的數(shù)據(jù),還有1種就是使用注解,
這個(gè)正告信息就沒(méi)了,
放在變量前面也行:
在jdk源碼中這個(gè)注解也到處都是
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE}) @Retention(RetentionPolicy.SOURCE) public @interface SuppressWarnings { /** * The set of warnings that are to be suppressed by the compiler in the * annotated element. Duplicate names are permitted. The second and * successive occurrences of a name are ignored. The presence of * unrecognized warning names is <i>not</i> an error: Compilers must * ignore any warning names they do not recognize. They are, however, * free to emit a warning if an annotation contains an unrecognized * warning name. * * <p>Compiler vendors should document the warning names they support in * conjunction with this annotation type. They are encouraged to cooperate * to ensure that the same names work across multiple compilers. */ String[] value(); }
String[] value();我剛開始以為是方法,后來(lái)發(fā)現(xiàn)理解錯(cuò)了,value是參數(shù)名,String[]是參數(shù)類型,
如果想要使用這個(gè)注解,就必須最少添加1個(gè)參數(shù),這些參數(shù)值都是定義好的,以下:
比如這么使用:
如果只有1個(gè)參數(shù)的話可以這么使用
@SuppressWarnings("all")
如果是多個(gè)參數(shù)的話,這么使用:
@SuppressWarnings(value={"all","unchecked"})
自定義注解:
使用@interface自定義注解時(shí),自動(dòng)繼承了java.lang.annotatin.Annotation
@interface用來(lái)聲明1個(gè)注解
格式:public @interface 注解名
其中每個(gè)方法實(shí)際上是聲明1個(gè)配置參數(shù),就和我們上面講的SuppressWarnings1樣,
方法的名稱就是參數(shù)的名稱
返回值類型就是參數(shù)的類型(返回值類型只能是基本類型,Class,String,enum)
可以通過(guò)default來(lái)聲明參數(shù)的默許值
如果只有1個(gè)參數(shù)成員,1般參數(shù)名為value.
如果1個(gè)注解中甚么都沒(méi)有的話就是1個(gè)標(biāo)記注解,比如:
@Target(ElementType.METHOD) @Retention(RetentionPolicy.SOURCE) public @interface Override { }沒(méi)有定義參數(shù)和參數(shù)類型,
在android studio中定義1個(gè)注解類:在這里選擇,
package com.annotation; /** * Created by admin on 2017/1/11. */ public @interface MyAnnotation { }它默許是繼承了Annotation,就像你隨意定義1個(gè)Person,它也是隱士的繼承了Object類1樣,
1般定義注解都要在這個(gè)注解上定義2個(gè)元注解,那末甚么是元注解呢?
元注解:
元注解的作用就是負(fù)責(zé)注解其他的注解,對(duì)注解進(jìn)行描寫,java定義了4個(gè)標(biāo)注的meta-annotation類型,他們被用來(lái)對(duì)其他Annotation類型的說(shuō)明,分別有以下4個(gè):
@Target:用于描寫注解的使用范圍(也就是說(shuō)注解可以被用在甚么地方),
public @interface Target { ElementType[] value(); }
它是有參數(shù)名和參數(shù)類型的,上面已說(shuō)明了,在這就不描寫了
@Retention:表示在甚么級(jí)別保存該注釋信息,用于描寫注解的生命周期
1般都是使用RUNTIME,由于你自定義注解肯定是希望通過(guò)反射在運(yùn)行時(shí)讀取啊,而前2者通知是在編譯時(shí)期,如果使用了RUNTIME,那末就包括前2者,由于它生命周期最長(zhǎng),如果定義了前2者反射是讀取不到的.
@Documented:Documented 注解表明這個(gè)注解應(yīng)當(dāng)被 javadoc工具記錄. 默許情況下,javadoc是不包括注解的. 但如果聲明注解時(shí)指定了 @Documented,則它會(huì)被 javadoc 之類的工具處理, 所以注解類型信息也會(huì)被包括在生成的文檔中
現(xiàn)在在eclipse中如何演示生成1個(gè)文檔:
第1步點(diǎn)擊項(xiàng)目:選擇Export
第2步:
第3步:
第4步:在eclipse下運(yùn)行生成文檔
第5步:在之前選擇寄存文檔的目錄中找到生成的文檔:
看到這個(gè)相信大家都明白了,jdk中文或英文文檔是否是有這個(gè)了,然后點(diǎn)擊index.html查看
@Inherited:允許子類繼承父類的注解
上面把元注解講完了,現(xiàn)在自定義注解:
package com.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Created by admin on 2017/1/11. */ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface MyAnnotation { String name(); }
解釋:
發(fā)現(xiàn)報(bào)錯(cuò)了,解決這類辦法有2個(gè)方法
第1個(gè)方法:
設(shè)置默許值:
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface MyAnnotation { String name() default ""; }
第2種方法:
public class Test { @MyAnnotation(name="zhou") public void test(){ } }這就是自定義注解了,我寫的是1個(gè)簡(jiǎn)單的,其實(shí)復(fù)雜的也就是所謂的參數(shù)多點(diǎn)而已,
使用反射讀取注解內(nèi)容
寫這個(gè)例子就是使用注解和反射知識(shí)動(dòng)態(tài)的生成1條sql語(yǔ)句,現(xiàn)在很多框架估計(jì)也是這么干的,只是料想,沒(méi)看過(guò)網(wǎng)上那些3方數(shù)據(jù)庫(kù)框架的源碼,
package com.annotation; /** * Created by admin on 2017/1/11. */ @UserAnnotion("table_user") public class User { @AttrsAnnotation(columnName = "id",type ="int",len = 10) private int id; @AttrsAnnotation(columnName = "name",type ="varchar",len = 10) private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }對(duì)類名進(jìn)行注解跟表名進(jìn)行xiangguan
package com.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Created by admin on 2017/1/11. */ @Target(value= {ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface UserAnnotion { String value();//與表名對(duì)應(yīng) }類中的屬性和表字段進(jìn)行相干聯(lián)通過(guò)注解的方式
package com.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 修飾表中屬性的注解 * Created by admin on 2017/1/11. */ @Target(value= {ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) public @interface AttrsAnnotation { String columnName() default ""; String type() default ""; int len() default 10; }終究動(dòng)態(tài)的生成sql語(yǔ)句:
/** * 讀取User中的數(shù)據(jù) 動(dòng)態(tài)生成sql語(yǔ)句 */ public void table(){ try { Class clazz = Class.forName("com.annotation.User"); if(clazz!=null){ UserAnnotion userAnnotion = (UserAnnotion) clazz.getAnnotation(UserAnnotion.class); String table_name = userAnnotion.value();//獲得表名 Field nameFiled = clazz.getDeclaredField("name"); Field idFiled = clazz.getDeclaredField("id"); AttrsAnnotation nameFiledAnnotation = nameFiled.getAnnotation(AttrsAnnotation.class); AttrsAnnotation idFiledAnnotation = idFiled.getAnnotation(AttrsAnnotation.class); String tabpPre = "CREATE TABLE IF NOT EXISTS "; String sql=tabpPre+table_name+"("+"_id INTEGER PRIMARY KEY AUTOINCREMENT"+","+nameFiledAnnotation.columnName()+" "+nameFiledAnnotation.type()+"("+nameFiledAnnotation.len()+")"+","+idFiledAnnotation.columnName()+" "+idFiledAnnotation.type()+")"; Log.e(TAG,"SQL="+sql); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } }結(jié)果:
CREATE TABLE IF NOT EXISTS table_user(_id INTEGER PRIMARY KEY AUTOINCREMENT,name varchar(10),id int)
如圖調(diào)用:
如果知道這些理論,以后看3方數(shù)據(jù)庫(kù)框架應(yīng)當(dāng)輕松很多的,就寫到這吧