注解
java.Annotation
Annotation的作用:可以唄其他程序讀取
Annotation的格式
-
注解是:@注釋名 在代碼中存在,還可以添加一些參數(shù)
?@SuppressWarnings(values="unchecked")
-
通過(guò)反射,可以訪問(wèn)數(shù)據(jù)。
內(nèi)置注解
@override :定義在java.lang.Override中,此注解只適用于修飾方法,標(biāo)識(shí)一個(gè)方法聲明打算重寫(xiě)父類的另一個(gè)方法。
@Deprecated :定義在java.lang.Deprecated中,此方法用于修飾方法,類,屬性。表示廢棄元素
@SuppressWarings :定義在java.lang.SuppressWarings中,用來(lái)抑制編譯時(shí)的警告信息。
public class Demo01 extends Object {
//重寫(xiě)的注解
@Override
public String toString() {
return super.toString();
}
//不推薦使用的注解,但是可以使用
@Deprecated
public static void test() {
System.out.println("Deprecated");
}
@SuppressWarnings("all")
public static void test2() {
ArrayList arrayList = new ArrayList();
}
public static void main(String[] args) {
test();
}
}
元注解
元注解就是負(fù)責(zé)注解其他的注解,Java定義了四個(gè)標(biāo)準(zhǔn)的meta-annotation類型,他們用來(lái)提供對(duì)其他annotation類型操作說(shuō)明
可以從java.lang.annotation中找到(@Target,@Retention,@Docimented,@Inherited)
@Target:用于描述注解的使用范圍({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention:標(biāo)識(shí)需要在什么級(jí)別保存該注解信息,用于描述注解的生命周期(SOURCE<CLASS<RENTIME)
@Docimented:說(shuō)明注解將被包含在javadoc中
@Inherited:說(shuō)明子類可以繼承父類中的該注解
自定義注解
使用@interface自定義注解
格式
public @interface MyAnnotation
{
}
public class Demo02 {
//注解可以顯示的復(fù)制,如果沒(méi)有默認(rèn)值,就一定要注解賦值
@MyAnnotation(name = "nice",schools = {"1234","2314"})
public void test(){}
@MyAnnotation2("sdf")
public void test2(){}
}
@Target(value = {ElementType.METHOD,ElementType.TYPE})
@Retention(value =RetentionPolicy.RUNTIME)
@interface MyAnnotation
{
//注解的參數(shù):參數(shù)類型 參數(shù)名();
String name() default "";
int age() default 0;
int id() default -1;//代表不存在。
String[] schools() default {"erq","asds"};
}
@Target(value = {ElementType.METHOD,ElementType.TYPE})
@Retention(value =RetentionPolicy.RUNTIME)
@interface MyAnnotation2
{
//注解的參數(shù):參數(shù)類型 參數(shù)名();
String value() default "";
}
反射
java.Reflection
反射機(jī)制允許程序在執(zhí)行期間借助Reflection API獲取任何類的內(nèi)部信息,并能直接操作任意對(duì)象的內(nèi)部屬性級(jí)方法
Class c= Class.forName("java.lang.String")
獲得反射對(duì)象
public class Demo03 {
public static void main(String[] args) throws ClassNotFoundException {
//通過(guò)反射獲取類的class對(duì)象
Class c1 = Class.forName("com.darker.demo01.User");
Class c2 = Class.forName("com.darker.demo01.User");
Class c3 = Class.forName("com.darker.demo01.User");
//一個(gè)類在內(nèi)存中只有一個(gè)Class對(duì)象
//一個(gè)類被加載后,類的整個(gè)結(jié)構(gòu)都會(huì)被裝在Class對(duì)象中
System.out.println(c1.hashCode());
System.out.println(c2.hashCode());
System.out.println(c3.hashCode());
}
}
Class對(duì)象
方法名 |
功能說(shuō)明 |
static ClassforName(String name) |
返回指定類名name的Class對(duì)象 |
Object newInstance() |
調(diào)用缺省構(gòu)造函數(shù),返回Class對(duì)象的一個(gè)實(shí)例 |
getName() |
返回此Class對(duì)象鎖標(biāo)識(shí)的實(shí)體(類、接口、數(shù)組類或void)的名稱 |
Class getSuperClass() |
返回此Class對(duì)象的父類的Class對(duì)象 |
Class[] getinterfaces() |
獲取此Class對(duì)象的接口 |
ClassLoader getClassLoader() |
返回該類的類加載器 |
Constructor[] getConstructors() |
返回一個(gè)包含某些Constructor對(duì)象的數(shù)組 |
Method getMethod(String name,Class...T) |
返回一個(gè)Method對(duì)象,此對(duì)象的類型類paramaType |
Field[] GetDeclaredFields() |
返回Field對(duì)象的一個(gè)數(shù)組 |
獲取Class對(duì)象
public class Demo04 {
public static void main(String[] args) throws ClassNotFoundException {
Person person = new Student();
System.out.println("這個(gè)人是"+person.name);
//方式一:通過(guò)對(duì)象獲得
Class c1 = person.getClass();
System.out.println(c1.hashCode());
//方式二:forname獲得
Class c2 = Class.forName("com.darker.demo01.Student");
System.out.println(c2.hashCode());
//方式三:通過(guò)類名.class獲得
Class c3 = Student.class;
System.out.println(c3.hashCode());
//方式四,基本內(nèi)置類型的包裝類都有一個(gè)type屬性
Class c4 = Integer.TYPE;
System.out.println(c4.hashCode());
//獲得父類類型
Class c5 = c1.getSuperclass();
System.out.println(c5);
}
}
class Person{
public String name;
public Person() {
}
Person(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
'}';
}
}
class Student extends Person
{
public Student() {
this.name = "學(xué)生";
}
}
class Teacher extends Person
{
public Teacher() {
this.name = "老師";
}
}
哪些類型有Class對(duì)象
class:外部類,成員內(nèi)部類,靜態(tài)內(nèi)部類,局部?jī)?nèi)部類,局部?jī)?nèi)部類,匿名內(nèi)部類。
interface:接口
[]:數(shù)組
enum:枚舉
annotation:注解@interface
primitive type:基本數(shù)據(jù)類型
void
class內(nèi)存分析
public class Demo05 {
public static void main(String[] args) {
A a = new A();
System.out.println(A.m);
/*
1.加載到內(nèi)存,會(huì)產(chǎn)生一個(gè)類的對(duì)應(yīng)的Class對(duì)象
2.鏈接,鏈接后m=0
3.初始化
<cinit>(){
System.out.println("A類靜態(tài)代碼塊初始化");
m = 300;
m = 100;
}
*/
}
}
class A{
static {
System.out.println("A類靜態(tài)代碼塊初始化");
m=300;
}
static int m = 100;
public A()
{
System.out.println("A類的無(wú)參構(gòu)造初始化");
}
}
打印結(jié)果:
A類靜態(tài)代碼塊初始化
A類的無(wú)參構(gòu)造初始化
100
類的初始化
類的主動(dòng)引用(一定會(huì)發(fā)生類的初始化)
- 當(dāng)虛擬機(jī)啟動(dòng),先初始化main方法所在的類
- new一個(gè)類對(duì)象
- 調(diào)用靜態(tài)成員(除了final常量)和靜態(tài)方法
- 使用java.lang.reflect包的方法驚醒反射調(diào)用
- 當(dāng)初始化一個(gè)類,如果其父類沒(méi)有初始化,咋會(huì)初始化它的父類
類的被動(dòng)引用(一定不會(huì)發(fā)生類的初始化)
- 通過(guò)數(shù)組定義類引用
- 引用常量觸發(fā)此類的初始化(常量在鏈接階段就存入調(diào)用類的常量池中)
- 當(dāng)訪問(wèn)一個(gè)靜態(tài)域,只有真正聲明這個(gè)域的類才會(huì)被初始化。如:通過(guò)子類調(diào)用父類的靜態(tài)變量。
類加載器
引導(dǎo)類加載器
擴(kuò)展類加載器 ExtClassLoader 負(fù)責(zé)jre/lib/ext目錄下的jar包或者-D java.ext.dirs指定目錄下的jar包裝入工作庫(kù)
系統(tǒng)類加載器 AppClassLoader 負(fù)責(zé)java -classpath或-D java.class.path所指的目錄下的類與jar包裝如工作庫(kù),是最常用的加載器
public class Demo06 {
public static void main(String[] args) throws ClassNotFoundException {
//獲取系統(tǒng)類的加載器
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
System.out.println(systemClassLoader);
//獲取系統(tǒng)類加載器的父類加載器--》擴(kuò)展類接在其
ClassLoader parent = systemClassLoader.getParent();
System.out.println(parent);
//獲取擴(kuò)展類加載器的父類加載器--》根加載器(c/C++)
ClassLoader parent1 = parent.getParent();
System.out.println(parent1);
ClassLoader classLoader = Class.forName("com.darker.demo01.Demo06").getClassLoader();
System.out.println(classLoader);
//如何獲取系統(tǒng)類加載器可以加載的路徑
System.out.println(System.getProperty("java.class.path"));
}
}
獲取類的信息
public class Demo07 {
public static void main(String[] args) throws ClassNotFoundException {
Class aClass = Class.forName("com.darker.demo01.User");
//獲得類的名字
System.out.println("獲得類的名字");
//獲得包名+類名
System.out.println(aClass.getName());
//獲得類名
System.out.println(aClass.getSimpleName());
//獲得類的屬性
System.out.println("獲得類的屬性");
//只能找到public屬性
Field[] fields = aClass.getFields();
for (Field field : fields) {
System.out.println(field);
}
//能找到全部屬性
Field[] declaredFields = aClass.getDeclaredFields();
for (Field field : declaredFields) {
System.out.println(field);
}
//獲得類的方法
System.out.println("獲得類的方法");
//獲得本類和父類的所有public方法
Method[] methods = aClass.getMethods();
for (Method method : methods) {
System.out.println(method);
}
System.out.println("=========================");
//獲得本類所有方法
Method[] declaredMethods = aClass.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
System.out.println(declaredMethod);
}
}
}
通過(guò)反射操作類
public class Demo08 {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException, NoSuchFieldException {
Class c1 = Class.forName("com.darker.demo01.User");
//構(gòu)造一個(gè)對(duì)象
User user1 = (User) c1.newInstance();
System.out.println(user1);
//通過(guò)構(gòu)造器創(chuàng)建對(duì)象
Constructor constructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
Object user2 = constructor.newInstance("Darker", 1, 22);
System.out.println(user2);
//通過(guò)反射調(diào)用普通方法
User user3 = (User) c1.newInstance();
Method setName = c1.getDeclaredMethod("setName", String.class);
//invoke激活。(對(duì)象,“方法值”)
setName.invoke(user3, "darkerJO");
System.out.println(user3);
//通過(guò)反射操作屬性
User user4 = (User) c1.newInstance();
Field name = c1.getDeclaredField("name");
//不能直接操作私有屬性,需要關(guān)閉程序的安全監(jiān)測(cè),屬性或方法的setAccessible(true)
name.setAccessible(true);
name.set(user4, "DarkerGuo");
System.out.println(user4);
}
}
|