一、類加載器
1.java文件運行過程:
java源文件(.java)—(編譯器編譯)—>字節碼文件(.class)—(類加載器加載)—>字節碼對象(Class)
2.什麼是類加載器,作用是什麼?
類加載器就加載字節碼文件(.class)
3.類加載器的種類
類加載器有三種,不同類加載器加載不同的
1)BootStrap:引導類加載器:加載都是最基礎的文件
2)ExtClassLoader:擴展類加載器:加載都是基礎的文件
3)AppClassLoader:應用類加載器:三方jar包和自己編寫java文件
4.怎麼獲得類加載器?
ClassLoader 字節碼對象.getClassLoader();
示例代碼:
//獲得Demo字節碼文件的類加載器
Class clazz = Demo.class;//獲得Demo的字節碼對象
ClassLoader classLoader = clazz.getClassLoader();//獲得類加載器
//getResource的參數路徑相對classes(src),可以獲得classes(src)下的任何資源
//獲得classes(src)下的jdbc.properties資源
String path = classLoader.getResource("cn/zsl/test/jdbc.properties").getPath();
二、註解 @xxx
1.什麼是註解,註解作用
註解就是符合一定格式的語法 @xxxx
註解作用:
註釋:在閱讀程序時清楚----給程序員看的
註解:給jvm看的,給機器看的
註解在目前而言最主流的應用:代替配置文件
關於配置文件與註解開發的優缺點:
註解優點:開發效率高 成本低
註解缺點:耦合性大 並且不利於後期維護
2.jdk5提供的註解
@Override:告知編譯器此方法是覆蓋父類的
@Deprecated:標註過時
@SuppressWarnings:壓制警告
注:不同的註解只能在不同的位置使用(方法上、字段上、類上)
3.自定義註解
1)怎樣去編寫一個自定義的註解
關鍵字:@interface
註解的屬性:
語法:返回值 名稱();
注意:如果屬性的名字是value,並且註解的屬性值有一個,那麼在使用註解時可以省略value
註解示例1:
public @interface MyAnno {
String name();
//如果該註解只有一個value屬性,那麼在使用註解的時候可以在括號中直接傳值
// String value();
//default表示該註解的默認值,當設置了默認值,則使用該註解的時候該屬性可以不傳
int age() default 20;
}
使用註解1:
public class Demo {
//age不傳則默認爲20
@MyAnno(name = "zhangsan")
public void show(){
System.out.println();
}
}
註解示例2:
public @interface MyAnno {
String value();
String name() default "lisi";
int age() default 20;
}
使用註解2:
public class Demo {
//如果註解中有一個名爲value的屬性,並且不存在其他屬性或者其他屬性都給了默認值,那麼使用註解的時候就可以省略鍵值對的鍵直接給值
@MyAnno("zhangsan")
public void show(){
System.out.println();
}
}
2)元註解
元註解:代表修飾註解的註解,作用:限制定義的註解的特性
@Retention
SOURCE: 註解在源碼級別可見
CLASS:註解在字節碼文件級別可見
RUNTIME:註解在整個運行階段都可見
@Target
代表註解修飾的範圍:類上使用,方法上使用,字段上使用
FIELD:字段上可用此註解
METHOD:方法上可以用此註解
TYPE:類/接口上可以使用此註解
因此如果要通過字節碼解析註解,就必須把該註解的可見範圍設置爲RUNTIME,這樣在運行字節碼文件的時候才能獲取到該註解,否則會報空指針。
註解示例3:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnno {
String name() default "lisi";
String value();
int age() default 20;
}
使用註解3:
public class Demo {
@MyAnno("zhangsan")
public void show(){
System.out.println();
}
}
解析註解3:
public class TestMyAnno {
public static void main(String[] args) {
//解析show方法上面的@MyAnno
//直接目的:獲得show方法上的@MyAnno中的參數
try {
//獲得show方法的字節碼對象
Class clazz = Demo.class;
Method method = clazz.getMethod("show",null);
//獲得show方法上的@MyAnno
MyAnno annotation = method.getAnnotation(MyAnno.class);
//獲得@MyAnno上的屬性值
System.out.println(annotation.name());
System.out.println(annotation.age());
System.out.println(annotation.value());
} catch (NoSuchMethodException | SecurityException e) {
e.printStackTrace();
}
}
}
打印結果:
lisi
20
zhangsan