首页 > 编程语言 >java反射

java反射

时间:2023-08-11 09:22:15浏览次数:33  
标签:反射 java String System class println public out

1. 回顾

  1. 泛型: [泛型类,泛型接口,泛型方法]

    public class 类名<泛型标志...>{

    ​ //使用泛型标志定义数据类型

    }

    public interface 接口<泛型标志>{

    ​ //使用泛型标志定义抽象方法

    }

    public class 类名 implements 接口<泛型类型>{

    }

    public class 类名<泛型标志> implements 接口<泛型标志>{

    ​ //注意:类的泛型标志要和接口的泛型标志一致

    }

    修饰符 <泛型标志> 返回类型 方法名(泛型标志 参数名){

    }

  2. 泛型通配符 ?

  3. 泛型的上限 ? extends 类名

  4. 泛型的下限 ? super 类名

  5. 注解: 自定义注解

@Target(value="限制该注解可以使用在哪些位置。TYPE  METHOD Field PARAMTER")
@Retention(value="何时生效 SOURCE CLASS RUNTIME")
@Document(是否在生成api文档是显示该注解)
public  @interface 注解名{
    //注解中属性: 数据类型: 基本类型。字符串类型 以及上面类型的数组
    数据类型  属性名() [default 默认值]

}

使用注解: @注解名(只为value那么可以省略value 赋值的数组只有一个元素,省略{})

2. 正文

1. 什么反射?
2. 如何获取反射类对象.
3. 如何根据反射类获取类对象
4. 如何获取类中属性对象
5. 如何获取类中方法对象
6. 如何获取类中构造方法对象

3.什么是反射?

  1. 反射它是框架设计的灵魂。什么是框架: 框架就是把重复的代码分离出来形成一个框架,它是一个别人设计好的一个半成品,在使用时只要填入自己的业务代码。好处: 提高开发效率。
  2. 反射: 在运行时,它是把类中成员抽取为其他类对象的过程。

1691649503939

4. 获取反射Class

从上面的分析我们知道,任意一个字节码都会通过ClassLoader类加载器,加载到JVM内存中,并以Class类对象的形式存在。注意:一个类的字节码只会被加载一次。 获取Class类对象的方式有三种:

第一种: Class.forName("类路径")

第二种: 类名.class

第三中: 对象.getClass();

package com.aaa.javabast2;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.lang.reflect.Field;

public class a {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException {
        //1
        Class<?> aClass1 = Class.forName("com.aaa.javabast2.b");
        System.out.println(aClass1);
        //2
        b b = new b();
        Class<? extends com.aaa.javabast2.b> aClass = b.getClass();
        System.out.println(aClass);
        //3
        Class<com.aaa.javabast2.b> bClass = b.class;
        System.out.println(bClass);
    }
}
@Data
@NoArgsConstructor
@AllArgsConstructor
class b{
private String name;
private Integer age;
}

5. 通过反射类获取类对象

通过反射类Class类对象,调用newInstance()

package com.aaa.javabast2;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.lang.reflect.Field;

public class a {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException {

        Class<com.aaa.javabast2.b> bClass = b.class;
        System.out.println(bClass);

        //创建对象
        com.aaa.javabast2.b b1 = bClass.newInstance();
        System.out.println(b1);
        System.out.println("++++++++++++++");


    }
}
@Data
@NoArgsConstructor
@AllArgsConstructor
class b{
private String name;
private Integer age;
}

spring---spring.xml====>

--spring根据你传递的类路径----得到该类的反射类---并通过newInstance()创建类对象。

mybatis--=====> sqlSession.getMapper(UserDao.class);---->UserDao.class反射类---->mybatis创建UserDao接口的类对象。


6. 获取反射类中的属性成员对象

字节码中的属性成员被加载到内存中后会以Field类对象的形式存在。如何获取Field属性对象。

Class.getFields()
Class.getField(String)
Class.getDeclaredFields() 
Class.getDeclaredField(String) 
package com.aaa.javabast2;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.lang.reflect.Field;

public class a {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException {
        
        Class<com.aaa.javabast2.b> bClass = b.class;
        System.out.println(bClass);
        //创建对象
        com.aaa.javabast2.b b1 = bClass.newInstance();
        //获取本类中的所有属性
        Field[] declaredFields = bClass.getDeclaredFields();
        for (Field field:declaredFields){
            System.out.println(field);
        }

  
        Class<com.aaa.javabast2.b> bClass1 = b.class;
        com.aaa.javabast2.b b2 = bClass1.newInstance();
        //得到反射类中的age属性对象
        Field age = bClass1.getDeclaredField("age");
        //通过set属性为b对象赋值
        age.set(b2,15);
        System.out.println(b2);
    }
}
class c{
    public String address;
    private String phone;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
class b extends c{
private String name;
private Integer age;
}

6.2 Field类中具有的常用方法。

setAccessible(true): 设置允许访问私有属性
getAnnotation(注解.class):获取属性上的注解对象
package com.aaa.javabast2;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;

public class d {
    public static void main(String[] args) throws Exception {
        //1.获取反射类对象
        Class<Teacher> teacherClass = Teacher.class;
        //2.通过反射类得到类对象
        Teacher teacher = teacherClass.newInstance();
        //3. 得到反射类中的age属性对象
        Field ageField = teacherClass.getDeclaredField("age");
        //通过Age属性对象为teacher对象赋值  teacher.age=15
        ageField.set(teacher,15);

        Field nameField = teacherClass.getDeclaredField("name");
        //允许访问私有属性
        nameField.setAccessible(true);
        nameField.set(teacher,"刘德华");
        System.out.println(teacher);

        My annotation = nameField.getAnnotation(My.class);
        System.out.println(annotation.value());
    }
}
@Target(value = ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface My{
    String value();
}
class Teacher {
    @My(value = "姓名")
    private String name;
    public Integer age;

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

7. 获取方法类对象

获取对象的方法

Class.getMethods()
Class.getMethod(String, Class[])
Class.getDeclaredMethods()
Class.getDeclaredMethod(String, Class[]) 
package com.aaa.javabast2;

import java.lang.reflect.Method;

public class e {
    public static void main(String[] args) throws Exception {
        Class<Hello> helloClass = Hello.class;
        Hello hello = helloClass.newInstance();

        //获取本类中所有的Method方法对象
        Method[] declaredMethods = helloClass.getDeclaredMethods();
        for(Method m:declaredMethods){
            System.out.println(m);
        }

        //得到本类以及父类中public修饰的方法对象
        Method[] methods = helloClass.getMethods();
        for(Method m:methods){
            System.out.println(m);
        }
        
        //获取方法名为fun01的方法对象
        Method fun01 = helloClass.getMethod("fun01",int.class);
        System.out.println(fun01);

    }
}
class Hello{
    public String fun01(){
        System.out.println("~~~~~~~~~~~~~~~~~01");
        return "hello01";
    }
    public String fun01(int age){
        System.out.println("~~~~~~~~~~~~~~~~~01");
        return "hello01";
    }
    public String fun02(int age){
        System.out.println("~~~~~~~~~~~~~~02");
        return "hello01"+age;
    }
    private void fun03(){
        System.out.println("~~~~~~~~~~~~~~~03");
    }
}

7.2 Method类中常用的方法

invoke(): 执行该方法体。

getAnnotation()获取到方法上的的注释值

package com.aaa.javabast2;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;

public class e {
    public static void main(String[] args) throws Exception {
        Class<Hello> helloClass = Hello.class;
        Hello hello = helloClass.newInstance();

        Method f = helloClass.getMethod("fun01",int.class,String.class);
        //回调该方法   执行该方法
        Object result = f.invoke(hello, 15,"fun01");
        System.out.println("====================="+result);
        //获取到f方法上的的注释值
        My02 annotation = f.getAnnotation(My02.class);
        System.out.println(annotation.value());
    }
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface My02{
    String value();
}
class Hello{
    public String fun01(){
        System.out.println("~~~~~~~~~~~~~~~~~01");
        return "hello01";
    }
    @My02("fun01")
    public String fun01(int age,String name){
        System.out.println("~~~~~~~~~~~~~~~~~01=========="+age+";============="+name);
        return "hello01";
    }

    public String fun02(int age){
        System.out.println("~~~~~~~~~~~~~~02");
        return "hello01"+age;
    }
    private void fun03(){
        System.out.println("~~~~~~~~~~~~~~~03");
    }
}

package com.aaa.javabast2;

import java.lang.reflect.Method;

public class e {
    public static void main(String[] args) throws Exception {
        Class<Hello> helloClass = Hello.class;
        Hello hello = helloClass.newInstance();

		//invokde属性执行方法
        Method fun03 = helloClass.getDeclaredMethod("fun03",String.class);
        fun03.setAccessible(true);
        Object invoke = fun03.invoke(hello,"a");
        System.out.println("+++++++++++++++++++++++++++"+invoke);

    }
}
class Hello{
    public String fun01(){
        System.out.println("~~~~~~~~~~~~~~~~~01");
        return "hello01";
    }
    public String fun01(int age){
        System.out.println("~~~~~~~~~~~~~~~~~01");
        return "hello01";
    }
    public String fun02(int age){
        System.out.println("~~~~~~~~~~~~~~02");
        return "hello01"+age;
    }
    private void fun03(String a){
        System.out.println("~~~~~~~~~~~~~~~03"+a);
    }
}

8. 获取构造对象

Class.getConstructors() 
Class.getConstructor(Class[]) 
Class.getDeclaredConstructors() 
package com.aaa.javabast2;
import java.lang.reflect.Constructor;


public class f {
    public static void main(String[] args) throws Exception {
        Class<?> aClass = Class.forName("com.aaa.javabast2.S");
        Object o = aClass.newInstance(); //得到类对象---调用构造函数
            //获取本类以及父类所有构造函数
        Constructor<?>[] a = aClass.getDeclaredConstructors();
            for (Constructor constructor:a){
                System.out.println(constructor);
            }

            //获取本类中所以public构造函数
        Constructor<?>[] b = aClass.getConstructors();
            for (Constructor c:b){
                System.out.println(c);
            }
    }
}
class g{
    public g(){
        System.out.println("父类的无参构造函数");
    }
    public g(String name){
        System.out.println("这是父类的有参构造函数:"+name);
    }
}
class S extends  g{
    public S(){
        super();
        System.out.println("子类的无参");
    }
    public S(String name){
        System.out.println("子类的有参:"+name);
    }
    private S(Integer age){
        System.out.println("有参私有构造");
    }
}

8.2 Constructor类中常用的方法

package com.aaa.javabast2;

import java.lang.reflect.Constructor;

public class h {
    public static void main(String[] args) throws Exception {
        Class<?> aClass = Class.forName("com.aaa.javabast2.i");

        //得到本类以及父类无参构造函数
        Constructor<?> declaredConstructor = aClass.getDeclaredConstructor();
        Object o = declaredConstructor.newInstance();
        //得到本类以及父类的有参构造函数
        Constructor<?> declaredConstructor2 = aClass.getDeclaredConstructor(String.class);
        Object aaa = declaredConstructor2.newInstance("aaa");
        System.out.println(aaa);
    }
}
class j{
    public j(){
        System.out.println("父类的无参构造函数");
    }
    public j(String name){
        System.out.println("这是父类的有参构造函数:"+name);
    }
}
class i extends  j{
    public i(){
        super();
        System.out.println("子类的无参");
    }
    public i(String name){
        System.out.println("子类的有参:"+name);
    }
    private i(Integer age){
        System.out.println("有参私有构造");
    }
}

标签:反射,java,String,System,class,println,public,out
From: https://www.cnblogs.com/226zjw/p/17622184.html

相关文章

  • java_数据类型
    graphLR;java数据类型-->基本数据类型java数据类型-->引用数据类型1.基本类型graphLR;基本类型-->数值型基本类型-->字符型("字符型(char[2字节])")基本类型-->布尔型("布尔型(boolean[1字节]存放true/false)")数值型-->整数("整数(byte[1......
  • 【Java】从头开始的Java复健day4
    用的书:《Java从入门到精通》day1(3.1-3.3):【Java】从头开始的Java复健day1day2(3.4-3.8):【Java】从头开始的Java复健day2day3(4.1-4.3):【Java】从头开始的Java复健day3第四章流程控制4.5小结略略4.6练习题目写输出里了publicclassJava_test4_6{public......
  • 如何使用原生 JavaScript Canvas API 实现视频中的绿幕背景替换功能 All In One
    如何使用原生JavaScriptCanvasAPI实现视频中的绿幕背景替换功能AllInOneCanvas&Videodemoschroma-keying/greenscreeneffectconstprocessor={};processor.doLoad=functiondoLoad(){constvideo=document.getElementById("video");this.vid......
  • 《深入理解Java虚拟机》读书笔记:垃圾收集算法
    由于垃圾收集算法的实现涉及大量的程序细节,而且各个平台的虚拟机操作内存的方法又各不相同,因此本节不打算过多地讨论算法的实现,只是介绍几种算法的思想及其发展过程。垃圾收集算法概要 1、标记-清除算法标记-清除算法最基础的收集算法是“标记-清除”(Mark-Sweep)算法,算法分......
  • 【JavaScript36】HTML DOM创建/插入/删除/替换元素
    createElement创建元素document.createElement()可以创建一个元素document.createTextNode()创建一个文本节点appendChild()方法可向节点的子节点列表的末尾添加新的子节点。<divid="demo"><pid="p1">这是文本内容</p></div><script>//div下添加一个子元......
  • 【JavaScript34】获取和修改属性节点
    根据W3C的HTMLDOM标准,HTML文档中的所有内容都是节点:整个文档是一个文档节点每个HTML元素是元素节点HTML元素内的文本是文本节点每个HTML属性是属性节点注释是注释节点属性节点比如有一个p标签元素节点<pid="p2"class="text-center">点我看看</p>-那......
  • 【JavaScript35】innerText 和 innerHTML
    获取内容时innerHTML从对象的起始位置到终止位置的全部内容,还包括HTML标签。innerText会去掉标签的内容。innerText和innerHTML获取内容示例<divid="demo"><pid="p1"><strong>这是文本内容</strong></p>helloworld!</div><script>......
  • java_3种注释语句
    1.内容解释//内容单行注释/*内容*/多行注释/***内容*/文档注释2.多行注释与文档注释的区别多行注释:文档注释:JDK提供的工具javadoc解析注释的内容,就是生成了javaAPI文档3.生成步骤4.javadoc标签标签描述示例@author标识......
  • Java入门01
    JAVA的诞生c语言有汇编语言的特点,所以更贴合硬件,运行快效率高,有很多系统、编译器、数据库等都是由c语言编写的,包括C语言的指针可以直接操控内存,但是C语言却没有给一个工具去越界检查,导致很容易犯错,同时内存管理需要自己调试,且不能再编译的时候发现,导致很大一部分精力都被指针和......
  • Java 编程中关于异常处理的 10 个最佳实践
    异常处理在编写健壮的Java应用的过程中,扮演着一个重要的角色。它并不是应用的功能需求,且需要优雅的处理任何错误情况,例如资源不可用,错误的输入,null输入等等。Java提供几个异常处理功能,并通过try,catch和  finally关键字内嵌在语言的本身。Java编程语言同样允许创建新的异常和使......