一、类对象
类的对象
基于某个类new出来的对象,也称为实例对象
一个类可以创建无数个实例对象
类对象
类的加载产物,封装了一个类的所有信息,包括类名、父类、接口、属性、方法、构造方法等
类对象概念理解
类是具有相同属性的一类事物的集合,我们可以创造许多的类,
换个角度看,如果我们将这些类看做是一种实例对象,他们都来源于同一个Class类(模板类)实例化而来,
那么,每个类就对应一个Class对象;而且,每个类有且只有一个Class对象
所以这个Class对象就包含了,这个类的属性、方法、构造、类名、包名等信息
理解重点在于我们将类看做是一种对象看待
显示类的加载过程
添加运行参数,添加-verbose:class
,确定,启动即可
可以看到,程序运行时加载了很多类,包括jdk,Object等
二、获取类对象
1.通过类的对象获取
Student s = new Student();
Class c = s.getClass();
2.通过类名获取
Class c = 类名.class;
3.通过静态方法获取
Class c = Class.forName("包名.类名");
演示
第三种方式有检查异常,因为输入的包名地址可能不对,需要处理异常
public class TestPerson {
public static void main(String[] args) throws Exception{
List list = new ArrayList();
list.add(1);
list.add(2);
Class<?> class1 = list.getClass();
Class<?> class2 = ArrayList.class;
Class<?> class3 = Class.forName("java.util.ArrayList");
System.out.println(class1);
System.out.println(class1.hashCode());
System.out.println(class2);
System.out.println(class2.hashCode());
System.out.println(class3);
System.out.println(class3.hashCode());
}
}
注释
-
结果显示这三种方式获取的是同一个类对象
-
推荐使用第三种方式,前两种对代码依赖性太强,第三种是字符串更加灵活,在编译期间可以没有,运行期有就可以
三、常用方法
public String getName()
获取当前类对象代表的类名
public Package getPackage()
获取当前类对象代表的类的包名
public Class<? super T> getSuperclass
获取当前类对象代表的父类名
public Class<?>[] getInterfaces()
获取当前类对象代表的类实现的接口
public Constructor<?>[] getConstructors()
获取当前类对象代表的类的构造对象数组
public Contructor getConstructor()
获取默认的那个无参构造
public T newInstance()
使用上面得到的构造对象创建这个类的实例
public Method[] getMethods()
获取当前类对象代表的类的方法
public Field[] getFields()
获取类的属性
演示
准备Person类,添加无参构造、含参构造、get/set方法,toString方法
public class Person {
String name;
int age;
public Person() {
System.out.println("无参构造执行了");
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
1.获取无参构造,创建实例对象
public class TestPerson {
public static void main(String[] args) throws Exception{
Class<?> class1 = Class.forName("com.swy.Person");
Constructor<?> con = class1.getConstructor();
Person person1 = (Person)con.newInstance();
System.out.println(person1.toString());
System.out.println(person1.hashCode());
Person person2 = (Person)con.newInstance();
System.out.println(person2.toString());
System.out.println(person2.hashCode());
}
}
如果只是创建无参对象,也可以直接用类对象调用方法newInstance
创建,底层还是在执行上述方法
Class<?> class1 = Class.forName("com.swy.Person");
Person person3 = (Person) class1.newInstance();
2.获取含参构造,创建对象
getContructor()
方法需要添加参数,需要获取哪个含参构造,就把这个构造的参数对象按照顺序添加进来
public class TestPerson {
public static void main(String[] args) throws Exception{
Class<?> class1 = Class.forName("com.swy.Person");
Constructor<?> con2 = class1.getConstructor(String.class,int.class);
Person person4 = (Person) con2.newInstance("Rose",18);
System.out.println(person4.toString());
}
}
3.使用反射获取类中方法,并调用方法
给Person类添加一下几个方法测试
public void eat(){
System.out.println(name+"吃东西");
}
public void eat(String food){
System.out.println(name+"吃"+food);
}
private void privateMethod(){
System.out.println("执行了私有方法");
}
public static void