注解与反射
注解
可被其他程序(如:编译器)读取,可以对程序做出解释
以@注释名在代码中存在
内置注解
@Override
必须重写父类存在的方法,否则报错
@Deprecated
表示不鼓励使用该类或者方法或者属性
@SuppressWarnings(“xxx”)
抑制编译时的警告信息
元注解
用于注解其他注解的注解
@Target(value={})
约束其他注解可以使用的地方
@Retention
表示注解在什么地方还有效,一般写runtime
runtime>class>sources
@Documented
表示是否将注解生成在Javadoc中
@inherited
子类可以继承父类的注解
自定义注解
通过@interface 注解名{}来定义注解
参数类型+参数名+()来定义参数
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@interface MyInterface{
String name() default ""; //如果不设置默认值,则必须填写
int age();
}
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@interface MyInterface1{
String value(); //当只有一个参数,且参数名为value时,可以省略参数名
}
@MyInterface(age = 18)
public static void test1(){}
@MyInterface1("")
public static void test2(){}
反射
Java被视为动态语言的关键,反射机制允许程序在执行期间借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性和方法
优点
可以实现动态创建对象和编译,体现很大的灵活性
缺点
影响性能
Class类
只能由系统创建,反射可以获取class类的对象, 在jvm中有且只有一个实例
package Reflection;
public class Test01 {
public static void main(String[] args) throws ClassNotFoundException {
Person person = new Student();
//Class类的创建方法
//方式一:通过对象获得
Class c1 = person.getClass();
//方式二:通过完整的类名获得
Class c2 = Class.forName("Reflection.Student");
//方式三:通过类名.class获得
Class c3 = Student.class;
//基本内置类都会有一个type属性
Class c4 = Integer.TYPE;
System.out.println(c1.hashCode());
System.out.println(c2.hashCode());
System.out.println(c3.hashCode());
System.out.println(c4.hashCode());
}
}
class Person{
public String name;
public int age;
public Person() {
}
}
class Student extends Person{
public Student() {
this.name = "学生";
}
}
class Teacher extends Person{
public Teacher(){
this.name = "老师";
}
}
通过反射获取类的信息
package Reflection;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
//获取类的信息
public class Test02 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
User user = new User();
Class c1 = user.getClass();
//获得类的名字
System.out.println(c1.getName()); //获得类名+包名
System.out.println(c1.getSimpleName()); //获得类名
//获得类的属性
Field[] fields = c1.getFields(); //获取方法中的公共属性
fields =c1.getDeclaredFields(); //获取方法中的所有属性
for(Field field:fields){
System.out.println(field);
}
//获得类的方法
Method[] method = c1.getMethods(); //获得子类和父类的所有方法
method = c1.getDeclaredMethods(); //获得本类的所有方法
for(Method method1:method){
System.out.println(method1);
}
System.out.println("**********************");
Method method1 = c1.getMethod("getName",null); //获取指定的方法
System.out.println(method1);
//获取构造器,方法同上。。。
}
}
通过反射动态创建对象
package Reflection;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
//通过反射动态地创建对象
public class Test03 {
public static void main(String[] args) throws Exception {
Class c1 = Class.forName("Reflection.User");
//方式一
Object o = c1.newInstance(); //该类必须有无参构造器
//方式二
Constructor constructor = c1.getConstructor(String.class,int.class,int.class);
User user = (User)constructor.newInstance("chenchenchen",18,1);
System.out.println(user);
//调用对象中的方法
Method setName = c1.getMethod("setName", String.class);
setName.invoke(user,"陈琛琛");
System.out.println(user.getName());
//调用对象中的属性
Field name = c1.getDeclaredField("name");
name.setAccessible(true); //设置是否开启权限
name.set(user,"haha");
System.out.println(user.getName());
}
}
性能对比
package Reflection;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
//通过反射动态地创建对象
public class Test03 {
public static void main(String[] args) throws Exception {
Class c1 = Class.forName("Reflection.User");
//方式一
Object o = c1.newInstance(); //该类必须有无参构造器
//方式二
Constructor constructor = c1.getConstructor(String.class,int.class,int.class);
User user = (User)constructor.newInstance("chenchenchen",18,1);
System.out.println(user);
//调用对象中的方法
Method setName = c1.getMethod("setName", String.class);
setName.invoke(user,"陈琛琛");
System.out.println(user.getName());
//调用对象中的属性
Field name = c1.getDeclaredField("name");
name.setAccessible(true); //设置是否开启权限
name.set(user,"haha");
System.out.println(user.getName());
}
}
泛型类型
package Reflection;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
//获取泛型的真实类型
public class Test05 {
public static void test1(Map<String,User> map, List<String> list){
System.out.println("test1");
}
public Map<String,User> test2(){
System.out.println("test2");
return null;
}
public static void main(String[] args) throws NoSuchMethodException {
Method method = Test05.class.getMethod("test1", Map.class, List.class);
Type[] genericParameterTypes = method.getGenericParameterTypes(); //获得泛型的参数类型数组
for (Type genericParameterType : genericParameterTypes) { //打印类型
if(genericParameterType instanceof ParameterizedType){ //如果是参数化类型,将其进行强制转换,然后调用方法获取真实参数类型
Type[] actualTypeArguments = ((ParameterizedType) genericParameterType).getActualTypeArguments();
for (Type actualTypeArgument : actualTypeArguments) { //打印真实类型
System.out.println(actualTypeArgument);
}
}
}
method = Test05.class.getMethod("test2");
Type genericReturnType = method.getGenericReturnType();
if(genericReturnType instanceof ParameterizedType){
Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments();
for (Type actualTypeArgument : actualTypeArguments) {
System.out.println(actualTypeArgument);
}
}
}
}
ORM
package Reflection;
import java.lang.annotation.*;
import java.lang.reflect.Field;
public class ORM {
public static void main(String[] args) throws NoSuchFieldException {
Final f = new Final();
Class c1 = f.getClass();
Annotation annotation = c1.getAnnotation(Table.class);
System.out.println(annotation);
//获取注解中的数据
Table table = (Table)annotation;
System.out.println(table.value());
Field name = c1.getDeclaredField("id"); //属性的注解需要先获取到属性值
name.setAccessible(true);
TableTest annotation1 = name.getAnnotation(TableTest.class);
System.out.println(annotation1.tableName());
System.out.println(annotation1.type());
System.out.println(annotation1.length());
}
}
@Table("db_Test")
class Final{
@TableTest(tableName = "Test",type = "String",length = 10)
private String name;
@TableTest(tableName = "Test",type = "int",length = 2)
private int age;
@TableTest(tableName = "Test",type = "int",length = 10)
private int id;
public Final() {
}
public Final(String name, int age, int id) {
this.name = name;
this.age = age;
this.id = id;
}
@Override
public String toString() {
return "Final{" +
"name='" + name + '\'' +
", age=" + age +
", id=" + id +
'}';
}
}
//类名注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Table{
String value(); //表名
}
//属性的注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface TableTest{
String tableName();
String type();
int length();
}