1.理解Class類對象。
Class類被創建後的對象就是Class對象,注意,Class對象表示的是自己手動編寫類的類型信息,比如創建一個Shapes類,那麼,JVM就會創建一個Shapes對應Class類的Class對象,該Class對象保存了Shapes類相關的類型信息。實際上在Java中每個類都有一個Class對象,每當我們編寫並且編譯一個新創建的類就會產生一個對應Class對象並且這個Class對象會被保存在同名.class文件裏(編譯後的字節碼文件保存的就是Class對象),那爲什麼需要這樣一個Class對象呢?是這樣的,當我們new一個新對象或者引用靜態成員變量時,Java虛擬機(JVM)中的類加載器子系統會將對應Class對象加載到JVM中,然後JVM再根據這個類型信息相關的Class對象創建我們需要實例對象或者提供靜態變量的引用值。需要特別注意的是,手動編寫的每個class類,無論創建多少個實例對象,在JVM中都只有一個Class對象,即在內存中每個類有且只有一個相對應的Class對象,挺拗口,通過下圖理解(內存中的簡易現象圖):
到這我們也就可以得出以下幾點信息:
- Class類也是類的一種,與class關鍵字是不一樣的。
- 手動編寫的類被編譯後會產生一個Class對象,其表示的是創建的類的類型信息,而且這個Class對象保存在同名.class的文件中(字節碼文件),比如創建一個Shapes類,編譯Shapes類後就會創建其包含Shapes類相關類型信息的Class對象,並保存在Shapes.class字節碼文件中。
- 每個通過關鍵字class標識的類,在內存中有且只有一個與之對應的Class對象來描述其類型信息,無論創建多少個實例對象,其依據的都是用一個Class對象。
- Class類只存私有構造函數,因此對應Class對象只能有JVM創建和加載
- Class類的對象作用是運行時提供或獲得某個對象的類型信息,這點對於反射技術很重要(關於反射稍後分析)。
例子:
package com.ssl;
public class Person {
private int age;
public String name;
public Person() {
System.out.println("Person的無參構造");
// TODO Auto-generated constructor stub
}
public Person(int age, String name) {
super();
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void say(){
System.out.println("Person的say方法");
}
}
package com.ssl;
public class Student extends Person{
private double height;
double weight;
protected int classid;
public char gender;
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
public double getWeight() {
return weight;
}
public void setWeight(double weight) {
this.weight = weight;
}
public int getClassid() {
return classid;
}
public void setClassid(int classid) {
this.classid = classid;
}
public char getGender() {
return gender;
}
public void setGender(char gender) {
this.gender = gender;
}
public Student(double height, double weight, int classid, char gender) {
super();
this.height = height;
this.weight = weight;
this.classid = classid;
this.gender = gender;
}
public Student(int age, String name, double height, double weight,
int classid, char gender) {
super(age, name);
this.height = height;
this.weight = weight;
this.classid = classid;
this.gender = gender;
}
private Student(double weight, int classid, char gender) {
super();
this.weight = weight;
this.classid = classid;
this.gender = gender;
}
public Student() {
super();
}
public void sleep(){
System.out.println("Student.sleep()");
}
//
}
package com.ssl;
import java.lang.reflect.Modifier;
public class Test {
public static void main(String[] args) throws ClassNotFoundException {
// TODO Auto-generated method stub
//獲取Class類對象的方法
//方法一:getclass
Student stu = new Student();
Class c1 = stu.getClass();
Class c2 = stu.getClass();
System.out.println(c1);
System.out.println(c2);
System.out.println(c1==c2);
//方法二:
Class c3 = Student.class;
Class c4 = Student.class;
System.out.println(c3);
System.out.println(c4);
System.out.println(c3==c4);
//方法三:常用
Class c5 = Class.forName("com.ssl.Student");
Class c6 = Class.forName("com.ssl.Student");
System.out.println(c5);
System.out.println(c6);
System.out.println(c5==c6);
//常見方法
//獲取類的全稱
System.out.println(c5.getName());
//獲取類的簡稱
System.out.println(c5.getSimpleName());
//獲取類的修飾符
System.out.println(c5.getModifiers());
System.out.println(Modifier.toString(c5.getModifiers()));
//獲取父類
System.out.println(c5.getSuperclass());
}
}
反射機制_Class類_反射操縱類中屬性,方法,構造器
package com.ssl.copy;
public class Person {
private int age;
public String name;
public Person() {
System.out.println("Person的無參構造");
// TODO Auto-generated constructor stub
}
public Person(int age, String name) {
super();
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void say(){
System.out.println("Person的say方法");
}
}
package com.ssl.copy;
public class Student extends Person{
private double height;
double weight;
protected int classid;
public char gender;
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
public double getWeight() {
return weight;
}
public void setWeight(double weight) {
this.weight = weight;
}
public int getClassid() {
return classid;
}
public void setClassid(int classid) {
this.classid = classid;
}
public char getGender() {
return gender;
}
public void setGender(char gender) {
this.gender = gender;
}
public Student(double height, double weight, int classid, char gender) {
super();
this.height = height;
this.weight = weight;
this.classid = classid;
this.gender = gender;
}
public Student(int age, String name, double height, double weight,
int classid, char gender) {
super(age, name);
this.height = height;
this.weight = weight;
this.classid = classid;
this.gender = gender;
}
private Student(double weight, int classid, char gender) {
super();
this.weight = weight;
this.classid = classid;
this.gender = gender;
}
public Student() {
super();
System.out.println("student無參構造");
}
public void sleep(){
System.out.println("Student.sleep()");
}
}
package com.ssl.copy;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class Test {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
Class c1 = Class.forName("com.ssl.copy.Student");
//創建對象,默認使用無參構造,如果沒有無參構造會報錯。如果無參構造爲私有的,那麼也會報錯
c1.newInstance();
//獲取構造函數,private形式的構造方法這種方法是獲取不到的。
System.out.println("=======================================");
Constructor[] constructors = c1.getConstructors();
for ( int i=0;i<constructors.length;i++){
System.out.println(constructors[i]);
}
//獲取構造函數,所有的都可以獲取到
System.out.println("==========================================");
Constructor[] declaredConstructors = c1.getDeclaredConstructors();
for ( int i=0;i<declaredConstructors.length;i++){
System.out.println(declaredConstructors[i]);
}
//獲取指定的構造函數
System.out.println("=============================================");
//獲取指定的空構造函數
Constructor con1= c1.getConstructor(null);
System.out.println(con1);
//根據參數獲取指定的構造函數
System.out.println("=============================================");
Constructor con2 = c1.getDeclaredConstructor(new Class[]{double.class,double.class,int.class,char.class});
System.out.println(con2);
//創建對象
Object o1 = con1.newInstance(null);
System.out.println(o1);
Object o2 = con2.newInstance(1.0,2.0,20,'男');
System.out.println(o2);
}
}
反射操縱類中的屬性:
package com.ssl.copy;
import java.lang.reflect.Field;
public class TestDemo {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException, InstantiationException, IllegalAccessException {
// TODO Auto-generated method stub
Class c1 = Class.forName("com.ssl.copy.Student");
//獲取屬性
//獲取子類和父類的public修飾的屬性、
Field[] fields = c1.getFields();
for (int i=0;i<fields.length;i++){
System.out.println(fields[i]);
}
System.out.println("=====================");
//獲去子類所有的屬性
Field[] fields2 = c1.getDeclaredFields();
for (int i=0;i<fields2.length;i++){
System.out.println(fields2[i]);
}
System.out.println("=====================");
//獲取特定屬性
Field field = c1.getField("gender");
System.out.println("field");
Field field2 = c1.getDeclaredField("weight");
System.out.println(field2);
Field field3 = c1.getDeclaredField("height");
System.out.println(field3);
//給屬性賦值
Student s = (Student)c1.newInstance();
field.set(s, "男");
System.out.println(s);
field3.setAccessible(true);
field3.setDouble(s, 12.1);
System.out.println(s);
}
}
反射操縱類中的方法:
package com.ssl.copy;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Test2 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Class c1 = Class.forName("com.ssl.copy.Student");
//獲取子類和父類的public的方法
Method[] methods = c1.getMethods();
for (int i=0;i<methods.length;i++){
System.out.println(methods[i]);
}
System.out.println("方法的個數是:"+methods.length);
//獲取子類的所有方法
Method[] methods1 = c1.getDeclaredMethods();
for (int i=0;i<methods1.length;i++){
System.out.println(methods[i]);
}
System.out.println("方法的個數是:"+methods1.length);
//獲取自動方法
Method m1 = c1.getMethod("toString",new Class[]{});
System.out.println(m1);
System.out.println("==================");
Method m2 = c1.getMethod("setClassid", new Class[]{int.class});
System.out.println(m2);
System.out.println("==============");
//執行方法:
Object o1 = c1.newInstance();
System.out.println(m1.invoke(o1,new Class[]{}));
}
}