1 - 獲取Class的三種方式
1.1 - Class.forName()
默認(rèn)從src根路徑開(kāi)始獲取class實(shí)例化對(duì)象
//字符串是完整的類名趁矾,包括包名
c1 = Class.forName("java.lang.String");
1.2 - getClass()
public static void main(String[] args) {
String s = "abc";
Student student = new Student("小A");
Class c = s.getClass();
Class stu = student.getClass();
System.out.println(c);
System.out.println(stu);
}
1.3 - Class屬性
任何類型都有class屬性
Class s = String.class;
2 - 實(shí)例化對(duì)象
Object o = class.newInstance();
newInstance()調(diào)用的是無(wú)參數(shù)構(gòu)造方法伍纫。如果無(wú)參被有參構(gòu)造覆蓋肴掷,會(huì)報(bào)錯(cuò)
public static void main(String[] args) throws IllegalAccessException, InstantiationException {
Class c=null;
try {
c = Class.forName("javase/Student.java");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Object o = c.newInstance();
}
newInstance()和new 對(duì)象有什么區(qū)別导犹?
反射機(jī)制更加靈活。如果想要?jiǎng)?chuàng)建不同的對(duì)象暖侨,只需要在配置文件中更改類名就可以創(chuàng)建不同的對(duì)象癣朗,而不用修改代碼
public static void main(String[] args) throws IllegalAccessException, InstantiationException, IOException, ClassNotFoundException {
//注意這里的默認(rèn)路徑是項(xiàng)目根目錄茅茂,不是src
FileReader reader = new FileReader("src\\javase\\reflect.properties");
Properties pro = new Properties();
//將文件中的數(shù)據(jù)加載到properties中
pro.load(reader);
reader.close();
String className = pro.getProperty("className");
//通過(guò)pro中的value獲取類
//className=javase.Student
Class c = Class.forName(className);
//通過(guò)類實(shí)例化對(duì)象
Object o = c.newInstance();
System.out.println(o);
}
如果想創(chuàng)建不同的類鹏溯,只需要修改配置文件中的className對(duì)應(yīng)的value即可
3 - 反射Field
獲取public修飾的屬性:getFields()
獲取所有屬性:getDeclaredFields()
獲取名字:class/field.getName() getSimpleName()
獲取屬性類型名:field.getType().getName()
獲取修飾符列表:getModifiers() 修飾符可能不止一個(gè)
public static void main(String[] args) {
Class stuclass = Class.forName("javase.reflect.Student");
//獲取public修飾的屬性
Field[] fields = stuclass.getFields();
for (Field f:fields
) {
System.out.println("共有屬性有:"+f.getName());
}
//獲取所有屬性
Field[] allfields = stuclass.getDeclaredFields();
for (Field f:allfields
) {
//獲取修飾符
String modifiers = Modifier.toString(f.getModifiers());
//獲取類型
String typeName = f.getType().getSimpleName();
//獲取名字
String fName = f.getName();
System.out.println(modifiers+" "+typeName+" "+fName);
}
}
訪問(wèn)屬性對(duì)象
修改屬性值:field.set(obj,vaule)
獲取屬性值:field.get(obj)
訪問(wèn)私有屬性需要打破封裝field.setAccessiable(true)
public static void main(String[] args) {
Class stuclass = Class.forName("javase.reflect.Student");
Object obj = stuclass.newInstance();
//獲取屬性
//這樣寫(xiě)的靈活性在于這個(gè)屬性名可以放在配置文件中
//以后的框架都是采用這種方式
Field noField = stuclass.getDeclaredField("no");
//賦值三要素:對(duì)象obj 屬性noField 值2
noField.set(obj,2);
//讀取屬性的值
//以前是對(duì)象.屬性 現(xiàn)在是屬性.get(對(duì)象)
System.out.println(noField.get(obj));
}
訪問(wèn)私有屬性
Field nameField = stuclass.getDeclaredField("name");
nameField.setAccessible(true);
nameField.set(obj,"小紅");
System.out.println(nameField.get(obj));
4 - 反射Method
獲取所有方法:Method[] methods=class.getDeclaredMethod()
獲取返回值類型:Class class = method.getReturnType()
獲取參數(shù)列表:Class[] class = method.getParameterTypes()
public static void main(String[] args) throws ClassNotFoundException {
Class stuclass = Class.forName("javase.reflect.Student");
//獲取類的所有方法
Method[] methods = stuclass.getDeclaredMethods();
//獲取方法返回值類型
for (Method m:methods
) {
System.out.println("返回值類型:"+m.getReturnType().getSimpleName());
Class[] paras =m.getParameterTypes();
System.out.print("參數(shù)列表有:");
for (Class c:paras
) {
System.out.print(c.getSimpleName()+"\t");
}
}
}
反射調(diào)用方法
確定一個(gè)方法需要:方法名和參數(shù)列表
因?yàn)榉椒梢灾剌d
class.getDeclaredMethod(className,參數(shù)列表)
調(diào)用方法的要素:
對(duì)象,方法名 參數(shù) 返回值
value = method.invoke(對(duì)象淹仑,實(shí)參)
public static void main(String[] args) {
Class stuclass = Class.forName("javase.reflect.Student");
//獲取對(duì)應(yīng)的方法
Method method = stuclass.getDeclaredMethod("dohomework", Student.class, String.class);
//創(chuàng)建對(duì)象
Object obj = stuclass.newInstance();
Field name = stuclass.getDeclaredField("name");
name.setAccessible(true);
name.set(obj,"張三");
//調(diào)方法
method.invoke(obj,obj,"9點(diǎn)");
}
5 - 反射Constructor
調(diào)用構(gòu)造方法創(chuàng)建對(duì)象
constructor.newInstance()
區(qū)分構(gòu)造方法靠形參
public static void main(String[] args) {
Class stuclass = Class.forName("javase.reflect.Student");
Constructor con = stuclass.getDeclaredConstructor(Integer.class,String.class);
Object obj = con.newInstance(1,"sam");
System.out.println(obj);
}