前言Class类
Class类常用方法总结
1getName():返回String形式的该类的名称。
2 newInstance():根据某个Class对象产生其对应类的实例,它调用的是此类的默认构造方法(没有默认无参构造器会报错)
3 getClassLoader():返回该Class对象对应的类的类加载器。
4 getSuperClass():返回某子类所对应的直接父类所对应的Class对象
5 isArray():判定此Class对象所对应的是否是一个数组对象
6 getComponentType() :如果当前类表示一个数组,则返回表示该数组组件的 Class 对象,否则返回 null。
7 getConstructor(Class[]) :返回当前 Class 对象表示的类的指定的公有构造子对象。
8 getConstructors() :返回当前 Class 对象表示的类的所有公有构造子对象数组。
9 getDeclaredConstructor(Class[]) :返回当前 Class 对象表示的类的指定已说明的一个构造子对象。
10 getDeclaredConstructors() :返回当前 Class 对象表示的类的所有已说明的构造子对象数组。
11 getDeclaredField(String) :返回当前 Class 对象表示的类或接口的指定已说明的一个域对象。
12 getDeclaredFields() :返回当前 Class 对象表示的类或接口的所有已说明的域对象数组。
13 getDeclaredMethod(String, Class[]) :返回当前 Class 对象表示的类或接口的指定已说明的一个方法对象。
14 getDeclaredMethods() :返回 Class 对象表示的类或接口的所有已说明的方法数组。
15 getField(String) :返回当前 Class 对象表示的类或接口的指定的公有成员域对象。
16 getFields() :返回当前 Class 对象表示的类或接口的所有可访问的公有域对象数组。
17 getInterfaces() :返回当前对象表示的类或接口实现的接口。
18 getMethod(String, Class[]) :返回当前 Class 对象表示的类或接口的指定的公有成员方法对象。
19 getMethods() :返回当前 Class 对象表示的类或接口的所有公有成员方法对象数组,包括已声明的和从父类继承的方法。
20 isInstance(Object) :此方法是 Java 语言 instanceof 操作的动态等价方法。
21 isInterface() :判定指定的 Class 对象是否表示一个接口类型
22 isPrimitive() :判定指定的 Class 对象是否表示一个 Java 的基类型。
23 newInstance() :创建类的新实例
新建Test类,测试创造类的Class实例
package day14;
public class Test {
public static void main(String[] args) {
Person p = new Person();
Class clazz = p.getClass(); //clazz对象中就包含对象p所属的Persion类的所有信息
System.out.println(clazz);
/**
* 三种方式创造clazz
*/
//方式一通过类名.class创建指定类的Class实例
Class c0 = Person.class;
//方式二通过一个类的实例对象的getClass()方法,获取对应实例对象的类Class实例
//Person p = new Person();
Class c1 = p.getClass();
//方式三通过Class 的静态方法forName(String className)来获取一个类的Class实例
//forName(String className) 方法中的参数是你获取的Class实例类的全路径 (包名类名)
try {
Class c2 = Class.forName("day14.Person");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
Person类
package day14;
public class Person {
public String name;
int age;
}
我们主要通过forName(String className)方式进行操作。
实验
建立两个接口,一个Student类一个Person类,让Student继承Persion类
person类
package day14;
public class Person {
public String name;
int age;
}
student类
package day14;
public class Student extends Person implements Move,Study {
public Student(){
System.out.println("调用的是public Student()");
}
public Student(String school){
System.out.println("调用的是public Student(String school)");
this.school=school;
}
private Student(String name, int age){
System.out.println("调用的是private Student(String name, int age)");
this.name = name;
this.age = age;
}
String school;
public void showInfo(){
System.out.println("学校是 :" + this.school);
}
@Override
public void moveType() {
System.out.println("学习中学的知识");
}
@Override
public void studyInfo() {
System.out.println("骑自行车上学");
}
}
接口1 Studey
package day14;
public interface Study {
void studyInfo();
}
接口2 Move
package day14;
public interface Move {
void moveType();
}
开始实验
主程序Test1
package day14;
import java.lang.reflect.Constructor;
public class Test1 {
public static void main(String[] args) {
try {
Class clazz = Class.forName("day14.Student"); //通过包名.类名的字符串,调用class.forname的实例
Class superClazz = clazz.getSuperclass(); //获取父类名字
System.out.println(superClazz.getName());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
输出父类
利用反射获取类的构造方法
下面开始演示getInterfaces()方法
获取类的公有的构造方法
修改Test1类
package day14;
import java.lang.reflect.Constructor;
public class Test1 {
public static void main(String[] args) {
try {
Class clazz = Class.forName("day14.Student"); //通过包名.类名的字符串,调用class.forname的实例
Class superClazz = clazz.getSuperclass(); //获取父类名字
System.out.println(superClazz.getName());
Class[] interfaces = clazz.getInterfaces(); //获取当前类的所有接口
for (Class c : interfaces){
System.out.println("接口 :" + c.getName());
}
Constructor [] cons = clazz.getConstructors(); //获取类的公有的构造方法
for(Constructor c : cons){
System.out.println("--------------------------------------------------------------------");
System.out.println("构造方法名称:" + c.getName()); //获取方法名称
System.out.println("构造方法名称:" + c.getName() + "构造方法的修饰符是:" + c.getModifiers()); //取得方法的修饰符
Class [] paramClass = c.getParameterTypes();
for(Class pc : paramClass){
System.out.println("构造方法:" + c.getName() + "的参数类型是:" + pc.getName());
}
System.out.println("--------------------------------------------------------------------");
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
getDeclaredConstructors()方法
package day14;
import java.lang.reflect.Constructor;
public class Test1 {
public static void main(String[] args) {
try {
Class clazz = Class.forName("day14.Student"); //通过包名.类名的字符串,调用class.forname的实例
Class superClazz = clazz.getSuperclass(); //获取父类名字
System.out.println(superClazz.getName());
Constructor [] cons1 = clazz.getDeclaredConstructors(); //获取类的所有方法,包括共有和私有
for(Constructor c : cons1){
System.out.println("--------------------------------------------------------------------");
System.out.println("构造方法名称:" + c.getName()); //获取方法名称
//返回数组1代表public 2代表private
System.out.println("构造方法名称:" + c.getName() + "构造方法的修饰符是:" + c.getModifiers()); //取得方法的修饰符
Class [] paramClass = c.getParameterTypes(); //获取class的构造方法的参数类型一个数组
for(Class pc : paramClass){
System.out.println("构造方法:" + c.getName() + "的参数类型是:" + pc.getName());
}
System.out.println("--------------------------------------------------------------------");
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
可以看的出getDeclaredConstructors()方法可以获取private私有方法,而且1代表public方法,2代表private方法.
通过反射的构造方法创建对象
package day14;
import java.lang.reflect.Constructor;
public class Test1 {
public static void main(String[] args) {
try {
Class clazz = Class.forName("day14.Student"); //通过包名.类名的字符串,调用class.forname的实例
Class superClazz = clazz.getSuperclass(); //获取父类名字
System.out.println(superClazz.getName());
try {
Object obj = clazz.newInstance(); //相当于调用Student类的1无参公有的构造方法
Student stu = (Student)obj;
//Constructor c = clazz.getConstructor(String.class); //指定获取一个有参数并且为String类型的公有的构造方法
//Student stu1 = (Student)c.newInstance("第一中学"); //newInstance实例化对象,相当于调用public
//System.out.println(stu1.school);
/**
* 通过反射机制可以强制调用私有的构造方法
*
*/
//Constructor c =clazz.getDeclaredConstructor(String.class,int.class);
//指定获取有两个参数,可获取到类的私有构造器(包括带有其他修饰符的构造器),但在使用private的构造器时,必须设置setAccessible()为true,才可以获取并操作该Constructor对象。
//c.setAccessible(true); //解除私有的封装,下面就可以对这个私有方法强制调用
//Student stu = (Student)c.newInstance("张三",12);
}catch(Exception e){
e.printStackTrace();
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
构造创建一个对象
public 无参方法:
Object obj = clazz.newInstance(); //相当于调用Student类的1无参公有的构造方法
Student stu = (Student)obj;
public 有参方法
Constructor c = clazz.getConstructor(String.class); //指定获取一个有参数并且为String类型的公有的构造方法
Student stu1 = (Student)c.newInstance("第一中学"); //newInstance实例化对象,相当于调用public
System.out.println(stu1.school);
private 有参方法
Constructor c =clazz.getDeclaredConstructor(String.class,int.class);
指定获取有两个参数,可获取到类的私有构造器(包括带有其他修饰符的构造器),但在使用private的构造器时,必须设置setAccessible()为true,才可以获取并操作该Constructor对象。
c.setAccessible(true); 解除私有的封装,下面就可以对这个私有方法强制调用
Student stu = (Student)c.newInstance("张三",12);
反射机制获取类的方法
package day14;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class Test1 {
public static void main(String[] args) {
try {
Class clazz = Class.forName("day14.Student"); //通过包名.类名的字符串,调用class.forname的实例
//Method[] ms = clazz.getMethods(); //获取的类的所有的公有的方法
Method[] ms = clazz.getDeclaredMethods(); //获取类所有的方法包括私有
for (Method m : ms) {
System.out.println("方法名:" + m.getName());
System.out.println("返回值类型:" + m.getReturnType());
System.out.println("修饰符:" + m.getModifiers());
Class[] pcs = m.getParameterTypes();//获取方法的参数类型,是一个数组,方法有几个参数,数组就有几个参数
if (pcs != null && pcs.length > 0) {
for (Class pc : pcs) {
System.out.println("参数类型:" + pc.getName());
}
}
System.out.println("-------------------------------------------------------------------------");
}
}catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
反射中getMethods 与 getDeclaredMethods 的区别
public Method[] getMethods()返回某个类的所有公用(public)方法包括其继承类的公用方法,当然也包括它所实现接口的方法。 public Method[]
getDeclaredMethods()对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。当然也包括它所实现接口的方法。