java基础性代码拾遗-7(反射)

反射的基本操作

  1. 获取类的名字
方法 描述
String getName() 获得包名+类名
String getSimpleName() 获得类的名字
Class cSuper=c.getSuperClass() 获取父类的Class对象
  1. 获得类的属性信息
方法 描述
Field getField(String fieldName) 得到public属性对象
Field[] getFields() 得到所有public属性对象
Field getDeclaredField(String fieldName) 得到任意指定名称的属性对象
Field[] c.getDeclaredFields() 得到所有的属性对象
field.getModifiers() 获得属性权限修饰符
field.getType() 获得属性类型
field.getName() 获得属性名称
  1. 获得类的方法
方法 描述
Method[] getDeclaredMethod() 得到所有方法对象
Method[] c.getMethods() 得到所有public方法对象
method.getModifiers() 获得方法访问权限
method.getReturnType() 获得方法返回值类型
method.getName() 获得方法名称
Class[] cs=method.getParameterTypes() 获取方法的参数
c.getTypeName() 获得参数类型
Constructor[] cons=c.getConstructors() 获得构造器
c.getConstructor(null) 获得无参构造方法
c.getConstructor(int.class,String.class,String.class) 获得指定重载的构造器
  1. 用反射操作对象
public class Test05 {
    public static void main(String[] args) throws Exception {
        Class c = Class.forName("demo.Person");
        Constructor cons = c.getConstructor(null);
        Person person = (Person) cons.newInstance();
        Field field = c.getDeclaredField("name");
        field.setAccessible(true); //不做安全检查,可以直接访问
        field.set(person, "王老五"); //对属性直接赋值
        System.out.println("取出name属性值:" + field.get(person));
        Method m = c.getDeclaredMethod("setName", String.class);
        m.invoke(person, "东施");
        Method m2 = c.getDeclaredMethod("getName", null);
        System.out.println("通过getter获得属性值:" + m2.invoke(person));
    }
}

提高反射的性能

  • 通过setAccessible()提高性能
    setAccessible(true)可以禁用java的安全检查。

反射操作泛型

Java中泛型仅是给编译器javac使用的,确保数据的安全性并免去强制类型转换。一旦编译完成,所有与泛型相关的类型全部擦除(擦除到Object)。
使用泛型直接读取泛型是不可行的,应为反射是操作编译以后的类的。
为操作泛型引入了ParameterizedType,GenericArrayType,TypeVariable,WildcardType(? extends Number或者? super Integer)。

public class TestGeneric {
    public void test01(Map<String, Person> map, List<Person> list, String s) {
        System.out.println("TestGeneric.test01()");
    }

    public Map<Integer, Person> test02() {
        System.out.println("TestGeneric.test02()");
        return null;
    }

    public String test03() {
        System.out.println("TestGeneric.test03()");
        return null;
    }

    public static void main(String[] args) throws NoSuchMethodException {
        Class c = TestGeneric.class;
        //参数为泛型
        Method test01 = c.getMethod("test01", Map.class, List.class, String.class);
        Type[] types = test01.getGenericParameterTypes();
        System.out.println(types.length);
        for (Type type : types) {
            System.out.println("#" + type);
            if (type instanceof ParameterizedType) {
                Type[] genericType = ((ParameterizedType) type).getActualTypeArguments();
                for (Type genType : genericType) {
                    System.out.println("泛型类型:" + genType);
                }
                System.out.println("--------------");
            }
        }
        System.out.println("------------------------");
        //返回值为泛型
        Method m2 = c.getMethod("test02", null);
        Type returnType = m2.getGenericReturnType();
        if (returnType instanceof ParameterizedType) {
            Type[] types2 = ((ParameterizedType) returnType).getActualTypeArguments();
            for (Type type : types2) {
                System.out.println("返回值的泛型类型:" + type);
            }
        }
        System.out.println("-----------------------");
        Method m3=c.getMethod("test03",null);
        Type returnType3=m3.getGenericReturnType();
        System.out.println(returnType3);
        System.out.println(returnType3 instanceof ParameterizedType);
    }
}

注解与反射

  • 原注解

@Target 注解应用范围

所修饰范围 取值ElementType
package包 PACKAGE
类,接口,枚举,Annotation类型 TYPE
类型成员(方法,构造方法,成员变量,枚举值) CONSTRUCTOR:用于描述构造器;FIELD:用于描述域;METHOD:用于描述方法;
方法参数和本地变量 LOCAL_VARIABLE:用于描述局部变量;PARAMETER:用于描述参数

@Retention 注解的生命周期。在什么级别保存注解信息。

取值RetentionPolicy 作用
SOURCE 在源文件中有效
CLASS 在class文件中有效
RUNTIME 在运行时有效,可以被反射机制读取

@Documented
@Inherited

  • 自定义注解的语法
    使用@interface定义自定义注解时,自动继承了java.lang.annotation.Annotation接口。

@interface 用来声明一个注解
其中每一个方法形式上声明了一个参数:
~ 方法的名称就是参数的名称
~ 返回值类型就是参数类型(返回值类型只能是基本数据类型,Class,String和enum)
~ 可以通过default来声明参数的默认值

String aName() default "";

~ 如果只有一个成员,一般参数名为value

注解元素必须要有值。自定义注解时通常使用空字符串或者0作为其默认值。也会使用-1表示不存在。

  • 反射读取注解

定义ORM表注解

@Target(ElementType.TYPE) //注解的使用范围
@Retention(RetentionPolicy.RUNTIME) //在运行时起作用
public @interface OrmTable {
    String value();
}

定义ORM字段注解

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface OrmField {
    String col();

    String type();

    int length();
}

定义javabean

@OrmTable("tb_student")
public class Student {
    @OrmField(col = "id", type = "int", length = 10)
    private int id;

    @OrmField(col = "stuname", type = "varchar", length = 20)
    private String name;

    @OrmField(col = "age", type = "int", length = 10)
    private int age;

    public Student() {
    }

    public Student(int id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

读取javabean的注解,然后…

import orm.anno.OrmField;
import orm.anno.OrmTable;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;

public class Test {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
        Class clazz = Class.forName("orm.entity.Student");
        //获取全部注解
        Annotation[] annotations = clazz.getDeclaredAnnotations();
        for (Annotation a : annotations) {
            System.out.println(a);
        }
        //获取指定注解
        OrmTable otb = (OrmTable) clazz.getDeclaredAnnotation(OrmTable.class);
        System.out.println("javabean的类注解:" + otb.value());
        //获取属性的注解
        Field field = clazz.getDeclaredField("name");
        OrmField ofd = field.getDeclaredAnnotation(OrmField.class);
        System.out.println("[" + ofd.col() + "," + ofd.type() + "," + ofd.length() + "]");
        //拼接SQL语句DDL,使用JDBC在数据库中执行,创建数据库表......
    }
}
发布了201 篇原创文章 · 获赞 8 · 访问量 2万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 书香水墨 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览