java进阶day35反射机制、注解

28 篇文章 0 订阅

本章重点是ReflectTest7和ReflectTest10

p822 回顾反射机制

  • 什么是反射机制?有什么用?

通过反射机制可以操作字节码文件,可以操作操作字节码创建对象。使程序更加灵活。

  • 反射机制相关的类在哪些包下?

java.lang.reflect.*

  • 反射机制相关的主要的类?

java.lang.Class
java.lang.reflect.Method
java.lang.reflect.Constructor
java.lang.reflect.Field

  • 在java中获取Class的三种方式

1、Class c = Class.forName(“完整类名”)
2、Class c = 对象.getClass()
3、Class c = 类名.class()

  • 获取了Class后,可以调用无参数构造方法实例化对象

Class c = Class.getClass(“java.util.Date”)
Object obj = c.newInstance()
需要注意的是newInstance底层调用的是该类的无参数构造方法。如果没有这个无参数构造方法,就会出现“实例化异常“
如果只想让一个方法的静态代码块执行,那么可以使用
Class.forName(完整类名)
这样类就加载了,类加载的时候静态代码块会执行

  • 获取文件的绝对路径,但是要求该文件放在类路径下,也就是放在src下。src是文件的根路径

String path = Thread.currentThread().getContextClassLoader().get.Resource(“写从src出发的i相对路径”).getPath();
在这里插入图片描述

  • 直接以流的方式返回

InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(“从rsc出发的相对路径”)

  • IO + Properties ,快速绑定属性资源文件。满足两点要求:1、该文件在src目录下2、该文件以.properties结尾。

ResourceBundle bundle = ResourceBundle.getBundle(“属性资源文件,注意不写扩展名”);
String className = bundle.getString(key);
System.out.println(key)

p823 获取Field【反射属性】

在这里插入图片描述

package com.bjpowernode.java.reflect;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class ReflectTest05 {
    public static void main(String[] args) throws Exception{

        //首先拿到整个类
        Class studentClass = Class.forName("com.bjpowernode.java.bean.Student");

        //获取完整类名
        System.out.println("完整名字:"+studentClass.getName());

        //获取简单名字
        System.out.println("简略名字:"+studentClass.getSimpleName());

        //拿到所有的public修饰的Field:getFields()
        Field[] fields = studentClass.getFields();
        System.out.println(fields.length);
        Field f = fields[0];//获取到的唯一的一个field是no,因为获取所有的public修饰的Field
        String fieldName = f.getName();
        System.out.println(fieldName);

        //拿到所有的Field:getDeclaredFields()
        //System.out.println(fs.length);
        System.out.println("=========================================");
        Field[] fs = studentClass.getDeclaredFields();

        for (Field field : fs) {
            //获取属性的名字
            System.out.println(field.getName());
            //获取属性的类型
            Class fieldType = field.getType();
            //String fName = fieldType.getName();
            String fName = fieldType.getSimpleName();
            System.out.println(fName);

            //获取属性的修饰符列表
            int i= field.getModifiers();//现在返回的修饰符是一个数字,怎么将他转换为字符串呢
            //静态方法,要使用类名.方法名区调用
            String fModifier = Modifier.toString(i);
            System.out.println(fModifier);

        }
        System.out.println("=========================================");


    }
}

在这里插入图片描述

p824 通过反射机制反编译一个类的Field属性【了解即可,不是重点】

在这里插入图片描述

package com.bjpowernode.java.reflect;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
//通过反射机制反编译一个类的Field
public class ReflectTest06 {
    public static void main(String[] args) throws Exception{

        //创建这个是为了拼接字符串
        StringBuilder s = new StringBuilder();

        //先拿到类
        //Class studentClass = Class.forName("com.bjpowernode.java.bean.Student");
        Class studentClass = Class.forName("java.lang.String");

        //s.append("public class Student{");
        //动态获取类名、动态获取修饰符
        s.append(Modifier.toString(studentClass.getModifiers())
                +" class "+studentClass.getSimpleName()+"{\n");

        //拿到全部的Field
        Field[] fields = studentClass.getDeclaredFields();

        //遍历
        for (Field field : fields){
            s.append('\t');//追加换行符
            s.append(Modifier.toString(field.getModifiers()));//追加修饰符
            s.append(" ");//追加空格
            s.append(field.getType().getSimpleName());//追加类型的简单名字
            s.append(" ");//追加空格
            s.append(field.getName());
            s.append(";\n");//追加分号
        }
        s.append("}");
        System.out.println(s);
    }
}

p825 通过反射机制访问一个对象属性【掌握】

在这里插入图片描述

在这里插入图片描述

package com.bjpowernode.java.reflect;

import com.bjpowernode.java.bean.Student;

import java.lang.reflect.Field;

/*
通过反射机制访问java对象的属性?
 */
public class ReflectTest07{
    public static void main(String[] args) throws Exception{
        /*
        不使用反射机制。怎么去访问对象属性'
        =================================================
         */
        Student student = new Student();
        /*
            给属性赋值
            三要素:1、对象student
                    2、属性no
                    3、1234
         */
        student.no=1234;


        //读取属性
        System.out.println(student.no);

        /*
        ==================================================
         */
        /*
        使用反射机制,如何访问对象属性

        /*
            给obj对象(student)的no属性赋值
            三要素:1、obj对象
                    2、noField属性
                    3、219912
        ==================================================
         */
        Class studentClass = Class.forName("com.bjpowernode.java.bean.Student");
        Object obj = studentClass.newInstance();//创建一个student对象(底层调用无参数构造方法)

        //获取no属性(根据属性的名称来获取Field)
        Field noField = studentClass.getDeclaredField("no");


        //给属性赋值
        noField.set(obj,219122);//给obj对象的no属性赋值219122


        /*
        获取属性的值,两个要素
            1、obj对象
            2、属性noField
         */
        System.out.println(noField.get(obj));
          /*
        使用反射机制,如何访问对象属性
        ==================================================
         */

    }
}

p826 访问对象属性【私有属性能否访问】

在这里插入图片描述

package com.bjpowernode.java.reflect;

import com.bjpowernode.java.bean.Student;

import java.lang.reflect.Field;

/*
通过反射机制访问java对象的属性?
 */
public class ReflectTest07{
    public static void main(String[] args) throws Exception{
        /*
        不使用反射机制。怎么去访问对象属性'
        =================================================
         */
        Student student = new Student();
        /*
            给属性赋值
            三要素:1、对象student
                    2、属性no
                    3、1234
         */
        student.no=1234;


        //读取属性
        System.out.println(student.no);

        /*
        ==================================================
         */
        /*
        使用反射机制,如何访问对象属性

        /*
            给obj对象(student)的no属性赋值
            三要素:1、obj对象
                    2、noField属性
                    3、219912
        ==================================================
         */
        Class studentClass = Class.forName("com.bjpowernode.java.bean.Student");
        Object obj = studentClass.newInstance();//创建一个student对象(底层调用无参数构造方法)

        //获取no属性(根据属性的名称来获取Field)
        Field noField = studentClass.getDeclaredField("no");


        //给属性赋值
        noField.set(obj,219122);//给obj对象的no属性赋值219122


        /*
        获取属性的值,两个要素
            1、obj对象
            2、属性noField
         */
        System.out.println(noField.get(obj));

        //访问私有属性
        Field nameField = studentClass.getDeclaredField("name");

        //但是现在不能设置私有属性,如何访问私有属性呢?
        //打破封装。但是有个缺点就是可能会带来安全隐患
        //这样设置之后,在在外部可以访问private。
        nameField.setAccessible(true);
        //给name属性赋值
        nameField.set(obj,"hajinwei");

        //获取name属性
        System.out.println(nameField.get(obj));

        //但是现在不能设置私有属性,如何访问私有属性呢?
          /*
        使用反射机制,如何访问对象属性
        ==================================================
         */



    }
}

p827 可变长度参数

在这里插入图片描述

package com.bjpowernode.java.reflect;

public class argsTest {
    public static void main(String[] args) {

        m();
        m(12);
        m(12,34);

        //m("abc");编译报错

        m3("abs","def","fdehf","gfg");

        System.out.println("=============");
        //可以直接传一个数组
        String[]  strs = {"dfhfj","dfshg","agyu","yurw"};
        m3(strs);
        System.out.println("=============");

        //直接在参数列表new数组
        m3(new String[]{"mazhognjie","hajinwei","zhangxinyue"});

    }

    public static void m(int...args){
        System.out.println("m方法执行了");
    }

    //必须在最后,且只能有一个
    public static void m2(int i,String...args){
        //
    }
    public static void m3(String...args){
        for (int i = 0; i < args.length; i++) {
            System.out.println(args[i]);
        }
    }
}

p828 反射机制的Method【了解】

package com.bjpowernode.java.reflect;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class ReflectTets08 {

    public static void main(String[] args) throws Exception{
        //拿到类
        Class userService = Class.forName("com.bjpowernode.java.service.UserService");

        //创建一个userService对象
        Object obj = userService.newInstance();

        //拿到Method,包括私有的。
        Method[] methods = userService.getDeclaredMethods();
        //System.out.println(methods.length);

        //遍历method
        for (Method method : methods ){
            //获取方法名
            System.out.println(method.getName());
            //获取返回值类型
            System.out.println(method.getReturnType().getSimpleName());

            //获取修饰符列表
            System.out.println(Modifier.toString(method.getModifiers()));

            //获取方法的修饰符列表(一个方法的参数可能有多个)
            Class[] parameterTypes = method.getParameterTypes();
            for (Class parametertype : parameterTypes){
                System.out.println(parametertype.getSimpleName());
            }
        }
    }

}

p829 反编译Method【了解】

package com.bjpowernode.java.reflect;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class ReflectTets09 {
    public static void main(String[] args) throws Exception{

        //准备一个StringBuider类型用来拼接
        StringBuilder s = new StringBuilder();
        //拿到类的信息
        //Class userServiceClass = Class.forName("com.bjpowernode.java.service.UserService");
        Class userServiceClass = Class.forName("java.lang.String");
        //s.append("public class userService {");
        s.append(Modifier.toString(userServiceClass.getModifiers())
                +" class "+userServiceClass.getSimpleName()+"{");

        //获取方法
        //拿到Method,包括私有的。
        Method[] methods = userServiceClass.getDeclaredMethods();

        for (Method  method: methods){
            //public boolean login(String name,String password){}

            //获取修饰符列表(public)

            s.append('\n');
            s.append('\t');
            s.append(Modifier.toString(method.getModifiers())+" ");

            //获取返回值类型
            s.append(method.getReturnType()+" ");

            //获取方法名
            s.append(method.getName()+"(");

            //获取参数类型及参数名String name,String password
            Class[] parameterTypes = method.getParameterTypes();
            for (Class parametertype : parameterTypes){
                //获取参数类型
                s.append(parametertype.getSimpleName()+" ");
                s.append(",");
                //获取参数名字
//                s.append(parametertype.get);
            }
            s.deleteCharAt(s.length() - 1);//删去第二个逗号。删除指定下标的字符
            s.append(")");

        }
        s.append("\n}");
        System.out.println(s);


    }
}

p830 反射机制调用方法【重点】

在这里插入图片描述
在这里插入图片描述

package com.bjpowernode.java.reflect;

import com.bjpowernode.java.service.UserService;

import java.lang.reflect.Method;

/**
 * 通过反射机制调用方法
 */
public class ReflectTest10 {
    public static void main(String[] args) throws Exception{
        /*
        不使用反射机制如何调用方法

         */
        //创建对象,调用方法
        UserService userService = new UserService();
        boolean loginSuccess = userService.login("admin","123456");
        //System.out.println(loginSuccess);
        System.out.println(loginSuccess ? "登录成功" : "登录失败");
        userService.logout();


        /*
        使用反射机制调用方法
        三要素:
            1、对象userService
            2、login方法名
            3、实参列表
            4、返回值
         */

        //拿到类
        Class serService = Class.forName("com.bjpowernode.java.service.UserService");

        //创建对象
        Object obj = serService.newInstance();//创建一个student对象(底层调用无参数构造方法)

        //拿到方法名
        Method loginMethod = userService.getClass().getDeclaredMethod("login", String.class, String.class);

        //开始调用。
        Object retValue = loginMethod.invoke(obj,"admin","123456");
        System.out.println(retValue);




    }
}

p831 反射Constructor

package com.bjpowernode.java.reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Parameter;

/*
通过反射机制反编译
 */
public class ReflectTest11 {

    public static void main(String[] args) throws Exception{

        //创建字符串用来拼接
        StringBuilder s = new StringBuilder();

        //拿到类
        Class vipClass = Class.forName("java.lang.String");

        s.append(Modifier.toString(vipClass.getModifiers())+" class "+vipClass.getSimpleName()+"{\n");//public+
        //s.append("public class Vip {\n");

        /*
        拼接构造方法
         */
        Constructor[] constructors = vipClass.getConstructors();
        for (Constructor constructor :constructors){

            s.append("\t");

            //获取修饰符
            s.append(Modifier.toString(vipClass.getModifiers()));

            //构造方法无返回值,获取方法名
            s.append(" "+vipClass.getSimpleName()+"(");
            //获取参数列表
            Class[] parameterTypes = constructor.getParameterTypes();
            for (Class parameterType : parameterTypes){

                //获取参数修饰列表
                s.append(parameterType.getSimpleName()+" ");
                //获取参数名
                s.append(",");

            }
            //s.deleteCharAt(s.length() - 1);//删除参数中的逗号时,这样删除会出现错误。public Vip){}所以删除之前需要判断参数列表长度,如果参数大于1才删除
            if (parameterTypes.length > 1){
                s.deleteCharAt(s.length() - 1);
            }
            s.append("){}\n");
        }




        s.append("}");
        System.out.println(s);
    }
}

p832 反射机制调用构造方法【非重点】

package com.bjpowernode.java.reflect;

import com.bjpowernode.java.bean.Vip;

import java.lang.reflect.Constructor;
import java.util.concurrent.ExecutionException;

/*
使用反射机制new对象
 */
public class ReflectTest12 {
    public static void main(String[] args) throws Exception {
        /*
        不使用反射机制new对象
         */
        Vip vip1 = new Vip();
        Vip vip2 = new Vip(123);
        Vip vip3 = new Vip(1234,"mazhongjie");
        Vip vip4 = new Vip(12345,"hgajinwei","19970410",true);


        /*
        使用反射机制创建对象
         */

        //拿到类
        Class c = Class.forName("com.bjpowernode.java.bean.Vip");

        //调用无参数构造方法
        Object obj = c.newInstance();
        System.out.println(obj);

        //调用带参数构造方法
        //先获取到这个有参数的构造方法
        Constructor constructor = c.getDeclaredConstructor(int.class,String.class,String.class,boolean.class);

        //调用构造方法new对象
        Object newobj = constructor.newInstance(110,"jack","1997-04-10",true);
        System.out.println(newobj);


        //获取无参构造方法
        Constructor con2 = c.getDeclaredConstructor();
        Object newobj2 = con2.newInstance();
        System.out.println(newobj2);
    }
}

p833 获取父类和父接口

在这里插入图片描述

反射机制结束

p834 注解怎么定义,怎么使用

在这里插入图片描述
在这里插入图片描述

p835 override注解【jdk内置注解】

java.lang下的注解
override方法只能注解方法。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

p836 元注解【注解注解的注解】在这里插入图片描述

在这里插入图片描述

p837 Deprecated注解

在这里插入图片描述

package com.bjpowernode.java.annotation;

//表示这个类已经过时
@Deprecated
public class AnnotationTest03 {
    public static void main(String[] args) {

    }

    @Deprecated
    public static void doSome(){
        System.out.println("do something");
    }


    public static void doOther(){
        System.out.println("do Other");
    }
}
class T{
    public static void main(String[] args) {

        AnnotationTest03 at = new AnnotationTest03();
        at.doSome();

        AnnotationTest03.doOther();
        AnnotationTest03.doSome();
    }
}

在这里插入图片描述

p838 注解中定义属性

在这里插入图片描述
在这里插入图片描述

p839 属性是value时可以忽略

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

p840 value属性的忽略

在这里插入图片描述

可以省略的前提是前面的注解中只有一个属性,并且是value。不能有多个。

p841 属性是一个数组

在这里插入图片描述
在这里插入图片描述

p842 反射注解

package com.bjpowernode.java.annotation5;

//只允许该注解可以标注类,方法

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

//Target元注解时一个value数组,其中的数组是一个枚举类型。ElementType.Type表示只能注解类。
@Target(value = {ElementType.TYPE,ElementType.METHOD})

//希望这个注解可以被反射
@Retention(RetentionPolicy.RUNTIME)
//@Retention(RetentionPolicy.SOURCE)
public @interface MyAnnotation {

    /*
    vaule属性
     */
    String value() default "北京大兴区";
}

package com.bjpowernode.java.annotation5;

@MyAnnotation("上海浦东区")
public class MyAnnotationTest {

    //不能注解Field
//    @MyAnnotation
//    int i;


    //不能出现在构造方法上
//    @MyAnnotation
//    public MyAnnotationTest() {
//    }

    @MyAnnotation
    public void doSome(){

    }
}

package com.bjpowernode.java.annotation5;

//反射机制反射
public class ReflectAnnotationTest {
    public static void main(String[] args) throws Exception{

        //拿到类
        Class c = Class.forName("com.bjpowernode.java.annotation5.MyAnnotationTest");

        //判断MyAnnotationTest类上面是否有Annotation
        System.out.println(c.isAnnotationPresent(MyAnnotation.class));//true

        //如果有注解,如何获取注解
        if (c.isAnnotationPresent(MyAnnotation.class)){
            //获取该注解对象
            MyAnnotation myAnnotation = (MyAnnotation) c.getAnnotation(MyAnnotation.class);

            //拿到注解对象
            System.out.println("类上面的注解对象:"+myAnnotation);

            //获取注解对象的属性,和调接口没区别
            String value = myAnnotation.value();
            System.out.println(value);



        }



        //判断String类上面是否有Annotation
        Class stringClass = Class.forName("java.lang.String");
        System.out.println(stringClass.isAnnotationPresent(String.class));//false
    }
}

p843 通过反射获取注解对象属性的值

package com.bjpowernode.java.annotation6;

import com.bjpowernode.java.annotation4.MyAnnotation;

import java.lang.reflect.Method;

public class MyAnnotationTest {


    @Myannotation(username = "admin",password = "454545")
    public void doSome(){

    }

    public static void main(String[] args) throws Exception{
        //通过反射机制取注解上的属性值
        //第一步,拿到类
        Class c = Class.forName("com.bjpowernode.java.annotation6.MyAnnotationTest");
        //System.out.println(c.getName());

        //拿到doSome()方法
        Method doSomeMethod = c.getDeclaredMethod("doSome");

        //判断该方法上是否有注解?
        if (doSomeMethod.isAnnotationPresent(Myannotation.class)){
            //如果有注解,如何拿到注解.使用doSomeMethod.getAnnotation()拿到Annotation类型的注解,
            // 然后强转为MyAnnotation类型。
            Myannotation myannotation = (Myannotation)doSomeMethod.getAnnotation(Myannotation.class);
            //拿到doSome()方法上的注解对象属性
            System.out.println(myannotation.username());
            System.out.println(myannotation.password());


        }


    }


}

package com.bjpowernode.java.annotation6;


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

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Myannotation {


    /**
     * username属性
     *
     */
    String username();


    /**
     * password属性
     *
     */
    String password();


}

p844 注解在实际开发中的作用

在这里插入图片描述

参考这个案例
> 参考
完结2021.4.7

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值