現(xiàn)在準(zhǔn)備研究1些源碼或框架,但是1些基礎(chǔ)的知識1定要懂,不然沒法看,比如設(shè)計模式,java基礎(chǔ)中的反射,泛型,注解,多線程,線程池,隊列等,現(xiàn)在很多框架都是這些知識雜糅而成的,
我們經(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就是注解,我們點擊進去看看,
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個注解類,在java.lang包下,發(fā)現(xiàn)聲明的注解Override上面有2個@Target和@Retention這2個注解,
@Target(ElementType.METHOD) 表示注解類(Override)使用再方法上
@Retention(RetentionPolicy.SOURCE) 表示使用再源碼中
@Target說明了Annotation所修飾的對象范圍
再點擊Target進去看看:
@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Target { ElementType[] value(); }我們發(fā)現(xiàn)
@Target(ElementType.ANNOTATION_TYPE)
()這個括號里的是啥東西呢,還是點擊進去看看源碼:
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后出來的,也就是說1.5之前是沒注解的,ElementType 這是1個枚舉類,這個枚舉類中定義了10個變量,哪這10個變量都是啥意思呢?
@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個聲明注解
@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個枚舉類,定義了3個變量
java內(nèi)置3大注解:
1:@Override
定義在java.lang.Override中,此注解只適應(yīng)于修飾方法,表示1個方法聲明打算重寫超類(父類)的另外一個方法聲明
package com.annotation; /** * Created by admin on 2017/1/10. */ public interface Person { String getName(); int getAge(); void sing(); }這是我們自己寫的1個接口,
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實現(xiàn)了Person接口,getName(),getAge(),sing()方法上都有@Override注解,表明這3個方法都是來自接口Person
2:@Deprecated
定義在java.lang.Deprecated中,此注解可修飾類,方法,屬性,表示不建議程序員使用這個方法,屬性,類等,表示它已過時,有更好的選擇或存在危險,下面我是我平時開發(fā)中很常見的過時正告:
3:@SuppressWarnings中,用來擬制編譯時正告信息,下面的代碼也是很常見的
哪怎樣修復(fù)呢?有2種,1種是依照提示去補充代碼,比如List要添加泛型,表示這個list存儲的是甚么類型的數(shù)據(jù),還有1種就是使用注解,
這個正告信息就沒了,
放在變量前面也行:
在jdk源碼中這個注解也到處都是
@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();我剛開始以為是方法,后來發(fā)現(xiàn)理解錯了,value是參數(shù)名,String[]是參數(shù)類型,
如果想要使用這個注解,就必須最少添加1個參數(shù),這些參數(shù)值都是定義好的,以下:
比如這么使用:
如果只有1個參數(shù)的話可以這么使用
@SuppressWarnings("all")
如果是多個參數(shù)的話,這么使用:
@SuppressWarnings(value={"all","unchecked"})
自定義注解:
使用@interface自定義注解時,自動繼承了java.lang.annotatin.Annotation
@interface用來聲明1個注解
格式:public @interface 注解名
其中每個方法實際上是聲明1個配置參數(shù),就和我們上面講的SuppressWarnings1樣,
方法的名稱就是參數(shù)的名稱
返回值類型就是參數(shù)的類型(返回值類型只能是基本類型,Class,String,enum)
可以通過default來聲明參數(shù)的默許值
如果只有1個參數(shù)成員,1般參數(shù)名為value.
如果1個注解中甚么都沒有的話就是1個標(biāo)記注解,比如:
@Target(ElementType.METHOD) @Retention(RetentionPolicy.SOURCE) public @interface Override { }沒有定義參數(shù)和參數(shù)類型,
在android studio中定義1個注解類:在這里選擇,
package com.annotation; /** * Created by admin on 2017/1/11. */ public @interface MyAnnotation { }它默許是繼承了Annotation,就像你隨意定義1個Person,它也是隱士的繼承了Object類1樣,
1般定義注解都要在這個注解上定義2個元注解,那末甚么是元注解呢?
元注解:
元注解的作用就是負責(zé)注解其他的注解,對注解進行描寫,java定義了4個標(biāo)注的meta-annotation類型,他們被用來對其他Annotation類型的說明,分別有以下4個:
@Target:用于描寫注解的使用范圍(也就是說注解可以被用在甚么地方),
public @interface Target { ElementType[] value(); }
它是有參數(shù)名和參數(shù)類型的,上面已說明了,在這就不描寫了
@Retention:表示在甚么級別保存該注釋信息,用于描寫注解的生命周期
1般都是使用RUNTIME,由于你自定義注解肯定是希望通過反射在運行時讀取啊,而前2者通知是在編譯時期,如果使用了RUNTIME,那末就包括前2者,由于它生命周期最長,如果定義了前2者反射是讀取不到的.
@Documented:Documented 注解表明這個注解應(yīng)當(dāng)被 javadoc工具記錄. 默許情況下,javadoc是不包括注解的. 但如果聲明注解時指定了 @Documented,則它會被 javadoc 之類的工具處理, 所以注解類型信息也會被包括在生成的文檔中
現(xiàn)在在eclipse中如何演示生成1個文檔:
第1步點擊項目:選擇Export
第2步:
第3步:
第4步:在eclipse下運行生成文檔
第5步:在之前選擇寄存文檔的目錄中找到生成的文檔:
看到這個相信大家都明白了,jdk中文或英文文檔是否是有這個了,然后點擊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)報錯了,解決這類辦法有2個方法
第1個方法:
設(shè)置默許值:
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface MyAnnotation { String name() default ""; }
第2種方法:
public class Test { @MyAnnotation(name="zhou") public void test(){ } }這就是自定義注解了,我寫的是1個簡單的,其實復(fù)雜的也就是所謂的參數(shù)多點而已,
使用反射讀取注解內(nèi)容
寫這個例子就是使用注解和反射知識動態(tài)的生成1條sql語句,現(xiàn)在很多框架估計也是這么干的,只是料想,沒看過網(wǎng)上那些3方數(shù)據(jù)庫框架的源碼,
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; } }對類名進行注解跟表名進行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();//與表名對應(yīng) }類中的屬性和表字段進行相干聯(liá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(value= {ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) public @interface AttrsAnnotation { String columnName() default ""; String type() default ""; int len() default 10; }終究動態(tài)的生成sql語句:
/** * 讀取User中的數(shù)據(jù) 動態(tài)生成sql語句 */ 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ù)庫框架應(yīng)當(dāng)輕松很多的,就寫到這吧