反射
类对象的概念:
对象之间的区别:
garen和teemo都是Hero对象,他们的区别在于,各自有不同的名称,血量,伤害值。
类之间的区别
Hero和Item都是类,他们的区别在于有不同的方法,不同的属性。
类对象,就是用于描述这种类,都有什么属性,什么方法的。
反射的概念:
反射是Java程序开发语言的特征之一,它允许动态地发现和绑定类、方法、字段,以及所有其他的由于有所产生的的元素。通过反射,能够在需要时完成创建实例、调用方法和访问字段的工作。
反射会做什么:
在运行时判断任意一个对象所属的类
在运行时构造任意一个类的对象
在运行时判断任意一个类所具有的成员变量和方法
在运行时调用任意一个对象的方法,通过反射甚至可以调用到private修饰的方法
生成动态代理
反射中,Class.forName 和 ClassLoader 区别:
两者都可用来对类进行加载。但差别在于:
Class#forName(…) 方法,除了将类的 .class 文件加载到JVM 中之外,还会对类进行解释,执行类中的 static 块。
ClassLoader 只干一件事情,就是将 .class 文件加载到 JVM 中,不会执行 static 中的内容,只有在 newInstance 才会去执行 static 块。
反射的常用类:
Java中反射相关的类大部分都在rt.jar下java.lang.reflect中,需要的类并不多,主要有以下几个:
java.lang.Class
Class类的实例表示正在运行的Java类和接口。
java.lang.reflect.Field
提供有关类或者接口的属性信息,以及对它的动态访问权限。反射的字段可能是一个类(静态)属性或实例属性,简单的理解可以把它看成一个封装反射类的属性的类。有点绕,慢慢体会吧。
java.lang.reflect.Constructor
提供关于类的单个构造方法的信息以及对它的访问权限。这个类和Field类不同,Filed类封装类反射类的属性,而Constructor类则封装类反射类的构造方法。
java.lang.reflect.Method
提供关于类和接口上单个方法的信息。所反映的方法可能是类方法或者实例方法(包括抽象方法)。这个类不难理解,他的作用就是用来封装反射类方法的一个类。
java.lang.reflect.Modifier
提供了用于解码类和成员访问修饰符的静态方法和常量。修饰符集合被表示为具有表示不同修饰符的不同位位置的整数。
java.lang.reflect.Array
提供了动态创解决数组和访问数组的静态方法,该类中的所有方法都是静态方法。
注解
贴一个关于注解的练习及其代码实现,以便日后复习。
实现一个自定义并解析注解的程序,该程序有三个文件,一个自定义注解文件,一个使用注解的类,一个解析注解的类。
//定义注解的类,该注解包含一个值,值的类型是String:
package test;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Documented
//表示运行时的注解
@Retention(RUNTIME)
//表示注解可以出现在类,属性,方法前面
@Target({TYPE,FIELD,METHOD})
public @interface Annotationa {
String author() default "student";
}
//使用注解的类:在该类中用自定义的注解去标注不同方法,并设置不同的注解值:
package test;
import java.lang.reflect.*;
import java.util.Scanner;
public class ParseAnnotation {
public static void main(String[] args) throws Exception{
String ch;
System.out.println("请输入匹配值");
Scanner s=new Scanner(System.in);
ch=s.nextLine();
Class c=Class.forName("second.UseAnnotation");
Method[] ms=c.getDeclaredMethods();
//遍历所有方法
for(Method m:ms) {
Annotationa ma=m.getAnnotation(Annotationa.class);
//System.out.println(ma.author());
if(ch!=null&&ch.equals(ma.author())) {
System.out.println("匹配成功!");
System.out.println(m.invoke(c.newInstance()));
break;
}else {
System.out.println("匹配失败!");
}
break;
}
}
}
//解析注解的类:该类实现输入一个字符串,利用该字符串去匹配使用注解的方法,如果字符串和注解的值一样,就表示匹配成功,就调用使用该注解的方法:
package test;
public class UseAnnotation {
@Annotationa(author="student1")
public void play1() {
System.out.println("调用了第一个方法");
}
@Annotationa(author="student2")
public void play2() {
System.out.println("调用了第二个方法");
}
@Annotationa(author="student3")
public void play3() {
System.out.println("调用了第三个方法");
}
}
参考资料:
【1】Datawhale开源资料_反射
【2】Datawhale开源资料_注解
【3】反射用途及实现
【4】java高级应用编程基础练习题