大约在一年前学习了java,基础不是很牢实。如今开始学习SSH框架技术,也复习到了前面的知识。想总结一下Class类的使用。
首先新建一个Pet类
Pet.java
package day190228;
public class Pet {
private String species;
public String getType() {
return species;
}
public void setType(String type) {
this.species = type;
}
public void eat() {
// TODO Auto-generated method stub
}
}
再新建一个接口
Animal.java
package day190228;
public interface Animal {
public void eat();//接口不能写方法体,是暴露的公共服务接口,不能看到具体的代码实现
}
接下来,新建一个Pig类继承Pet类实现Animal接口
Pig.java
package day190228;
public class Pig extends Pet implements Animal {
@Override
public void eat() {
// TODO Auto-generated method stub
System.out.println("eat plant");
}
public Pig(){ //构造函数不能继承
System.out.println("pink pig");
}
private Pig(String specise){
System.out.println("pink pig:"+specise);
}
public void jump(double height){
System.out.println("jump:"+height);
}
}
最后这是测试类Test01.java
Test01.java(获取某个对象的类以及类所实现的接口)
package day190228;
public class Testor01 {
public static void main(String[] args) {
//java.lang.String:类的全称
System.out.println(getObjClassName("abc"));
//day190228.Testor01:类的全称
System.out.println(getObjClassName(new Testor01()));
//
Pig pig = new Pig();
//获取它的父类
Class cls = pig.getClass();
//父类所对应的Class类的对象
Class pCls = cls.getSuperclass();
String parent = pCls.getName();
System.out.println(parent);
//获取pig对象的类所实现的接口
//一个类可以实现多个接口,所以获取到的应该是数组
Class[] icls = cls.getInterfaces();
for (int i=0 ; i<icls.length; i++){
System.out.println(icls[i].getName());
}
}
/*
* 获取某个对象的类的名称
*/
public static String getObjClassName(Object obj){
// 根据对象获取Class类的对象
// 方法 1:通过对象的getClass()方法来获取
// 2:根据类的class属性来获取,一般情况下不用
// Class cls = Object.class
// 3:在已知道类的全名称的情况下,利用类的全名称去获取
// Class.forName(类的全名称)
// ※forName是static方法,前面必须是用类名来调用
Class cls = obj.getClass();
//getName是Class类的对象的方法
return cls.getName();
}
}
控制台的结果:
测试类Test02.java
Test02.java( 获取某个对象的Class类的所对应的构造函数以及属性 )
package day190228;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Testor02 {
public static void main(String[] args) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
Class pcls = Pig.class;
//获取到全部的构造函数(包含私有的构造函数)
/*
获取某一个构造函数(根据参数的类型和个数)
pcls.getDeclaredConstructor(parameterTypes)
pcls.getConstructor(parameterTypes)
获取所有的构造函数
pcls.getDeclaredConstructors()
pcls.getConstructors()
※带有declared的方法,可以获取私有的构造函数。
不带declared的方法,只能获取共有的构造函数。
*/
Pig pig =null;
Constructor[] c1 = pcls.getDeclaredConstructors(); //私有和共有都可以获取
for (int i=0;i<c1.length;i++){
System.out.println("c1:" + c1[i].getParameterCount());//获取参数的个数
if (c1[i].getParameterCount() ==0) {
pig = (Pig)c1[i].newInstance();//根据这个构造函数去创造对应的类的对象,并将它向下转型
} else {
//会抛异常,因为带一个参数的构造函数是私有的。
//pig = (Pig)c1[i].newInstance("aaa");
}
if (pig != null) System.out.println("pig is not null");
}
Constructor[] c2 = pcls.getConstructors();
for (int i=0;i<c2.length;i++){
System.out.println("c2:" +c2[i].getParameterCount());
}
//Class类的对象获取属性的方法
/*
利用属性名获取某一个属性
pcls.getDeclaredField(name)
pcls.getField(name)
//获取所有属性
pcls.getDeclaredFields()
pcls.getFields()
※带有declared的方法,获取所有的属性,包括共有和私有,但是不包含从父类继承来的属性
* 不带declared的方法,只能获取公有的属性,包括从父类继承来的属性
*/
Pig pigx = new Pig();
Method eat = pcls.getMethod("eat");
//pigx.eat();
eat.invoke(pigx);//相当于第60行的代码,调用pigx对象的eat方法
Method jump = pcls.getMethod("jump", double.class);//“double.class”的意思是囊括了参数的类,类型为double
}
}
控制台的效果:(与构造函数的先后顺序无关)
有些我自己的见解,在表述上可能会含糊不清。若对代码或是注解有疑问的请在下方评论,会加以探讨,谢谢。