概念
功能
反射主要API
CLASS类
1.Class本身也是一个类
2.Class对象只能由系统创建
3.一个类再JVM中只会有一个Class实例
4.一个Class对象对应的是一个加载到JVM中的一个.class文件
5.每个类的实例都会记得自己是由哪个Class实例所生成
6.通过Class可以完整地得到一个类中的完整结构
java.lang.Class是反射的源头,.class文件加载到虚拟机后就会产生一个运行时类,通过这个类我们可以:
1.创建该类对象
2.获取对应运行时类的完整结构(属性、方法、内部类、父类,注解等)
实例
注解类
@Retention(RetentionPolicy.RUNTIME)
@Target( { ElementType.METHOD, ElementType.TYPE })
public @interface MyAnnotation {
int id() default 1;
String name();
// 定义枚举
public enum EnumType {
util, entity, service, model
}
// 设置默认值
public EnumType classType() default EnumType.util;
// 数组
int[] arr() default { 3, 7, 5 };
String methodUrl() default "";
}
接口类
public interface Myinterface extends Serializable{
void show();
}
泛型类
public class Creature<T> {
T cname;
public void printT(){
System.out.println("泛型打印:"+cname);
}
public void setCname(T cname) {
this.cname = cname;
}
}
父类
@MyAnnotation(name = "Parent")
public class Parent extends Creature<String> implements Myinterface {
private String name;
private Integer age;
public String pPub;
@Override
public void show() {
System.out.println("*******我是"+name+"******");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public static void printSta(){
System.out.println("我是静态方法!!");
}
private static void printPri(){
System.out.println("我是私有方法!!");
}
@Override
public String toString() {
return "Parent{" +
"name='" + name + '\'' +
", age=" + age +
", pPub='" + pPub + '\'' +
'}';
}
}
子类
@MyAnnotation(name = "Child")
public class Child extends Parent{
private String name;
private String add;
public String pub;
public Child() {
}
public Child(String name) {
this.name = name;
}
private void privateMethod() throws IllegalAccessException{
System.out.println("这是一个私有方法");
}
@Override
public String getName() {
return name;
}
@Override
public void setName(String name) {
this.name = name;
}
public String getAdd() {
return add;
}
public void setAdd(String add) {
this.add = add;
}
@MyAnnotation(name = "方法注解",arr = {1,2,3,4,5},methodUrl = "com.zy.demo.AnnotationDemo#Anprint")
public void printMsg(){
System.out.println("######我是"+name+"#####");
}
@Override
public String toString() {
return "Child{" +
"name='" + name + '\'' +
", add='" + add + '\'' +
'}';
}
}
获取Class类四种方式
public void test() throws ClassNotFoundException {
//1若已知具体的类,通过类的class属性获取,该方法最为安全可靠,程序性能最高
Class<Child> c1 = Child.class;
//2若已知类的实例,通过getClass获取
Child child = new Child();
Class<? extends Child> c2 = child.getClass();
//3若已知类的全类名,且该类在类路径下,可通过forName获取,需处理异常ClassNotFoundException
Class<?> c3 = Class.forName("com.zy.reflection.Child");
//4其他,通过类加载器来实现
ClassLoader classLoader = this.getClass().getClassLoader();
Class<?> c4 = classLoader.loadClass("com.zy.reflection.Child");
System.out.println("c1 = " + c1);
System.out.println("c2 = " + c2);
System.out.println("c3 = " + c3);
System.out.println("c4 = " + c4);
}
}
实例化对象
public void test() throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
Class<Child> c1 = Child.class;
//1.无参实例化对象
Child child = c1.newInstance();
System.out.println("child = " + child);
//2.有参实例化对象
Constructor<Child> ct = c1.getConstructor(String.class);
Child child1 = ct.newInstance("孩子");
System.out.println("child1 = " + child1);
}
获取类的完整结构
1.属性获取
public void test() throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
Class<Child> c1 = Child.class;
//只能获取运行时类中及其父类中声明为Public的属性
Field[] fields = c1.getFields();
for (Field f:fields) {
//1.获取每个属性权限修饰符
int Num = f.getModifiers();//权限对应数字
String str = Modifier.toString(Num);//数字转换权限
System.out.println("str = " + str);
//2.获取属性的类型
Class<?> type = f.getType();
System.out.println("type = " + type.getName());
//3.获取属性名
System.out.println("f.getName() = " + f.getName());
}
System.out.println("----------------------------------");
Field[] declaredFields = c1.getDeclaredFields();
for (Field f:declaredFields) {
int Num = f.getModifiers();
String str = Modifier.toString(Num);
System.out.println("str = " + str);
Class<?> type = f.getType();
System.out.println("type = " + type.getName());
System.out.println("f.getName() = " + f.getName());
}
}
2.方法获取
public void test(){
Class<Child> c1 = Child.class;
Method[] declaredMethods = c1.getDeclaredMethods();
for (Method m : declaredMethods) {
//1.注解
Annotation[] annotations = m.getAnnotations();
for (Annotation a: annotations) {
System.out.println(a);
}
//2.权限修饰符
String str = Modifier.toString(m.getModifiers());
System.out.print(str + " ");
//3.返回值类型
Class<?> returnType = m.getReturnType();
System.out.print(returnType.getName()+" ");
//4.方法名
System.out.print(m.getName()+" ");
//5.形参列表
System.out.print("(");
Class<?>[] parameterTypes = m.getParameterTypes();
for (int i = 0; i < parameterTypes.length; i++) {
System.out.print(parameterTypes[i].getName() + " args-"+i+" ");
}
//6.异常类型
Class<?>[] exceptionTypes = m.getExceptionTypes();
if(exceptionTypes.length != 0){
System.out.print("throws ");
}
for (int i = 0; i < exceptionTypes.length; i++) {
System.out.print(exceptionTypes[i].getName());
}
System.out.print(") ");
System.out.println();
}
}
3.构造器获取
public void test(){
Class<Child> c1 = Child.class;
Constructor<?>[] declaredConstructors = c1.getDeclaredConstructors();
for (Constructor c : declaredConstructors) {
System.out.println(c);
}
}
父类、接口、泛型获取
public void test(){
//1.获取运行时类的父类
Class<Child> c1 = Child.class;
Class<? super Child> superclass = c1.getSuperclass();
System.out.println("superclass = " + superclass);
//2.获取带泛型的父类
Type genericSuperclass = c1.getGenericSuperclass();
System.out.println("genericSuperclass = " + genericSuperclass);
//3.获取父类的泛型
Class<Parent> parentClass = Parent.class;
Type type1 = parentClass.getGenericSuperclass();
ParameterizedType param = (ParameterizedType)type1;
Type[] actualTypeArguments = param.getActualTypeArguments();
System.out.println(((Class)actualTypeArguments[0]).getName());
//4.获取实现的接口
Class<?>[] interfaces = parentClass.getInterfaces();
for (Class i : interfaces) {
System.out.println("i = " + i);
}
//5.获取所在的包
Package aPackage = parentClass.getPackage();
System.out.println("aPackage = " + aPackage);
}
调用
1.属性调用
public void test7() throws NoSuchFieldException, IllegalAccessException, InstantiationException {
Class<Parent> pc = Parent.class;
//1.获取运行时类中声明为public的指定属性并设置值
Field pPub = pc.getField("pPub");
Parent parent = pc.newInstance();
pPub.set(parent,"公共变量");
System.out.println(parent);
//2.获取运行时类中的指定属性并设置值
Field age = pc.getDeclaredField("age");
age.setAccessible(true);//必须设置,不然访问不了private
age.set(parent,22);
System.out.println(parent);
}
2.方法调用
public void test8() throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
Class<Parent> pc = Parent.class;
//1.调用无返回值方法
Parent parent = pc.newInstance();
Method show = pc.getMethod("show");
show.invoke(parent);
//2.调用返回值方法
Method toString = pc.getMethod("toString");
Object invoke = toString.invoke(parent);
System.out.println("invoke = " + invoke);
//3.调用静态方法
Method printSta = pc.getMethod("printSta");
printSta.invoke(pc);
//4.调用私有方法
Method printPri = pc.getDeclaredMethod("printPri");
printPri.setAccessible(true);
Object invoke1 = printPri.invoke(parent);
System.out.println("invoke1 = " + invoke1);
}
后续继续更新…