IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> java反射和注解 -> 正文阅读

[Java知识库]java反射和注解

1.反射与Class类

  • Java本是静态语言,但反射提供了动态语言的特性,通过反射可以获得任意类的所有结构,并可以任意操作类内部的属性和方法

  • 类加载完毕后,堆空间中会出现唯一的Class对象,这个对象clazz包含了该类的所有结构

  • Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的defineClass 方法自动构造的

  • 通过反射的方式获取对象效率远远不如直接new,当且仅当不能直接new对象的时候用反射创建对象,在主流框架中大量使用了反射
    普通方法即直接new

2.Class对象获取

一个类的Class对象无论用什么方式获取多少次,都是唯一的

new 目标类().getClass()

  • 不建议这样使用,已经可以直接new了就不要再反射获取对象了

  • new Student()的同时也会在堆空间产生全局唯一的Student类对象

    Student stu1 = new Student();//这一new 产生一个Student对象,一个Class对象。
    Class stuClass = stu1.getClass();//获取Class对象
    System.out.println(stuClass.getName());

目标类.class;

这种方法也不推荐,需要额外在调用处导入目标类的包,依赖过强

	//第二种方式获取Class对象
	Class stuClass2 = Student.class;

forName()方法——最常用

一般都第三种,一个字符串可以传入也可写在配置文件中等多种方法。

	//第三种方式获取Class对象
	try {
		Class stuClass3 = Class.forName("com.fanshe.Student");//全类名路径
	} catch (ClassNotFoundException e) {
		e.printStackTrace();
	}

基本数据类型和包装类

包装类.TYPE属性 相当于 基本数据类型.class属性

    Class<Integer> c1 = int.class;
    Class<Integer> c2 = Integer.TYPE;
    System.out.println(c1==c2);//true

源码
@SuppressWarnings(“unchecked”)
public static final Class TYPE = (Class) Class.getPrimitiveClass(“int”);

3.Class类常用方法

3.1静态方法

获取目标类的Class对象

3.2非静态方法

对于:Class c1 = Class.forName(“com.zjh.User”);

获取目标类实例

c1.newInstance()

获取目标类全类名路径

c1,getName()

获取父类的Class对象

c1.getSuperClass().getSuperClass()....可以一直链路向上调用

获取类的方法Method对象,invoke激活

不加Declared的getMethods()包括父类的方法

先获取Method对象(无参可以不填or填null),然后invoke调用方法

    Class c1 = Class.forName("filter.User");
    
    Method tell = c1.getMethod("tell", String.class);
    Object content = tell.invoke(new User(), "说话内容");
    System.out.println(content);//null无返回值

获取类的构造器

没有形参的就是获取所有,注意是否为s结尾复数,形参列表是Class对象; 没有Declared的就是只获取public修饰的

  • 批量的方法:返回数组
    public Constructor[] getConstructors():所有"公有的"构造方法
    public Constructor[] getDeclaredConstructors():获取所有的构造方法(包括私有、受保护、默认、公有)
  • 单个的方法,并调用:
    public Constructor getConstructor(**Class… parameterTypes **):获取单个的"公有的"构造方法:
    public Constructor getDeclaredConstructor(Class… parameterTypes):获取"某个构造方法"可以是私有的,或受保护、默认、公有;

调用时使用使用newInstance()

    Class c1 = Class.forName("filter.User");

    Constructor constructor = c1.getConstructor(String.class, int.class);
    Object u = constructor.newInstance("牛逼", 12);
    System.out.println(u);

获取类的属性

没有形参的就是获取所有,注意是否为s结尾复数,形参是String类型即指定获取某属性; 没有Declared的就是只获取public修饰的

  • 批量的:
    Field[] getFields():获取所有的"公有属性",包括父类
    Field[] getDeclaredFields():获取所有字段,包括:私有、受保护、默认、公有;
  • 获取单个的:
    public Field getField(String fieldName):获取某个"公有的"字段;
    public Field getDeclaredField(String fieldName):获取某个字段(可以是私有的)

————————————————————————————————————

如果使用getField(“name”)会由于私有属性抛java.lang.NoSuchFieldException: name

如果使用 Field name =c1.getDeclaredField(“name”);但是如果不 name.setAccessible(true); 就会抛异常
java.lang.IllegalAccessException

获取类的加载器

类的加载器分为:

c1.getClassLoader()

4.反射获取注解信息

4.1自定义注解

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface MyValue {
    //给字段赋值
    String value();
}


@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface MyTable {
    //表名
    String value();
}



@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface MyController {
    //URL
    String value();
}


@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface MyColumn {
    //字段名绑定
    String value();
}

4.2待绑定的Bean

@MyTable("table_people")
public class PeopleBean {

    @MyValue("zjh")
    @MyColumn("xx_name")
    private String name;

    @MyValue("18")
    @MyColumn("xx_age")
    private int age;

    @Override
    public String toString() {
        return "PeopleBean{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

4.3测试

@MyController("/com/baidu/www")
public class MyTest {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {

        //1.获取当前URL
        Class<MyTest> c1 = MyTest.class;
        MyController anno1 = c1.getAnnotation(MyController.class);
        String value1 = anno1.value();
        System.out.println("当前URL是:" + value1);


        //2.反射获取PeopleBean,并用@value对其赋值
        Class c2 = Class.forName("filter.PeopleBean");
        PeopleBean people= (PeopleBean)c2.newInstance();

        //3.PeopleBean直接获取的注解只有@MyTable
        Annotation[] annotations = c2.getDeclaredAnnotations();
        System.out.println("类级别的注解数:"+annotations.length);//1

        //4.获取类中所有不包括父类的属性
        Field[] fields = c2.getDeclaredFields();
        for (Field f : fields) {
            //@MyColumn绑定的字段信息
            MyColumn column = f.getDeclaredAnnotation(MyColumn.class);
            System.out.println(f.getName() + "绑定的表字段是:" + column.value());

            //@MyValue赋值操作
            MyValue Myvalue = f.getAnnotation(MyValue.class);
            String toValue = Myvalue.value();

            f.setAccessible(true);
            //对@MyValue目标绑定数据类型进行判断并赋值
            if(f.getType().getName().equals("int")){//判断属性是否是int类型
                f.set(people, Integer.parseInt(toValue));
            }else{
                f.set(people, toValue);
            }
        }

        System.out.println(people);
    }
}

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-04-18 17:27:33  更:2022-04-18 17:30:55 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 5:06:24-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码