1. 三種獲取類對(duì)象的方式
三種獲取類對(duì)象的方式,內(nèi)存中一個(gè)類只會(huì)有一個(gè)class對(duì)象。
public static void main(String[] args) throws ClassNotFoundException {
//通過反射來獲取對(duì)象的方式,包名+類名
//內(nèi)存中一個(gè)類只會(huì)有一個(gè)class對(duì)象
Class s1 = Class.forName("study.TestSort");
Class s2 = TestSort.class;
TestSort testSort = new TestSort();
Class s3 = testSort.getClass();
System.out.println(s1.hashCode());
System.out.println(s2.hashCode());
System.out.println(s3.hashCode());
}
2.哪些類有Class 對(duì)象?
- class
- 接口
- []數(shù)組
- enum 枚舉
- annotation 注解
- 基本數(shù)據(jù)類型
- void
3. 類的執(zhí)行順序:
首先是類的內(nèi)容:靜態(tài)變量、靜態(tài)初始化塊
再是 實(shí)例內(nèi)容:變量、初始化塊、構(gòu)造器
4.什么時(shí)候會(huì)發(fā)生類的初始化?
類分為主動(dòng)引用和被動(dòng)引用。主動(dòng)引用會(huì)發(fā)生類的初始化,被動(dòng)引用不會(huì)。
被動(dòng)引用
//引用類的常量不會(huì)發(fā)生初始化,常量通常在鏈接階段就存入調(diào)用類的常量池中了
public class ReflectTest {
static {
System.out.println("Main類被加載");
}
public static void main(String[] args) {
System.out.println(Son.M);
}
}
class Father{
static int b = 2;
static {
System.out.println("父類被加載");
}
}
class Son extends Father{
static {
System.out.println("子類被加載");
m = 300;
}
static int m = 100;
static final int M = 1;
}
輸出
Main類被加載
1
M被final修飾,不需要去初始化,在鏈接階段就存在了。
需要初始化的時(shí)候:
當(dāng)虛擬機(jī)啟動(dòng),會(huì)先初始化main方法所在的類。
當(dāng)new一個(gè)對(duì)象時(shí)。
調(diào)用類的靜態(tài)成員(除了final)和靜態(tài)方法也會(huì)初始化。
對(duì)類進(jìn)行反射調(diào)用。
public static void main(String[] args) {
System.out.println(Son.m);
}
前面例子里,打印這個(gè)
輸出
Main類被加載
父類被加載
子類被加載
100
5.通過反射獲取類的參數(shù)
public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
Class c1 = User.class;
//調(diào)用無參構(gòu)造函數(shù)
//User user = (User) c1.newInstance();
//用構(gòu)造器創(chuàng)建對(duì)象
Constructor constructor = c1.getDeclaredConstructor();
User user = (User) constructor.newInstance();
//獲取setName方法,如果setname方法是private,是無法invoke的,必須要setAccessible(true)
Method setNameMethod = c1.getDeclaredMethod("setName", String.class);
setNameMethod.setAccessible(true);
setNameMethod.invoke(user,"mmm");
System.out.println(user.getName());
}
對(duì)象關(guān)系映射
ORM 對(duì)象和表結(jié)構(gòu)對(duì)象
public class Test {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
Class s1 = Class.forName("reflect.Student");
//通過反射獲得value的值
Table table = (Table) s1.getAnnotation(Table.class);
String value = table.value();
System.out.println(value);
java.lang.reflect.Field field = s1.getDeclaredField("name");
Field fieldAnnotation = field.getAnnotation(Field.class);
System.out.println(fieldAnnotation.columnName());
}
}
@Table("db_student")
class Student{
@Field(columnName = "name", type = "varchar")
private String name;
@Field(columnName = "type", type = "int")
private int age;
}
//放在class上
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Table{
String value();
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface Field{
String columnName();
String type();
}