【JavaSE】反射&注解&Junit(19)

引言

  • 函数式编程那一块没有去仔细了解,只是能看出来是什么意思,网上了解了一下,好像是代码优化的知识;打算以后碰到了再具体了解。
  • 我SE方面学的速度相对快一些,因为之前学过一遍,但是当时没有系统学习;所以这次重新学一遍的时候知识理解的就相对容易些;而且我没有打暑假工,所以时间相对的也充沛一些。
  • 距离开学还有37天,我还是没有准备好。
  • 读万卷书,不如行万里路。

知识点总结

Junit

定义

单元测试(Junit) 是一个Java语言的单元测试框架,可以大大缩短你的测试时间和准确度。在Java中常用于测试一个类或方法;分为黑盒测试和白盒测试,本文以白盒测试讲解。

命名规则

   测试类名  *Test  
   测试包名  cn.itcase.test
   测试方法 test*()+void+空参+@Test【导Junit环境】
   判定结果  红色->error   绿色->right
   断言     Assert
   初始化方法@before  在测试方法之前自动执行
   @After  在测试方法之后自动执行

使用方法

1.自己创建


import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class Demo01 {
    public void add(int a,int b){
        System.out.println(a+b);
    }
    @Before
    public void before(){
        System.out.println("我是在测试方法之前执行的");
    }
    @Test
    //IDEA中会提示导入Junit测试环境
    public void Testadd(){
        int a=1;
        int b=2;
        System.out.println(a+b);
    }
    @After
    public void after(){
        System.out.println("我是在测试方法之后执行的");
    }
}

2.编译器生成
右击类名或方法名;
在这里插入图片描述

反射

定义

反射就是将类的各个部分封装为对象;
在这里插入图片描述

获取Class对象

1.Class.forName(“类名”);
返回与给定字符串名称的类或接口相关联的 类对象。
2.类名.class;
多用于参数的传递;
3.getClass();
常用于对象的获取字节码;

/*
获取Class对象
 */
public class Demo01 {
    public static void main(String[] args) throws ClassNotFoundException {
        Person  p1=new Person();
        Class cls3=Class.forName("反射.Person");
        //这个参数为包+类名,不含.java
       System.out.println(cls3);
       Class cls1=Person.class;
        System.out.println(cls1);
       Class cls2=p1.getClass();
        System.out.println(cls2);
        System.out.println(cls1==cls2);
        System.out.println(cls2==cls3);

    }
}
============================
从结果中可以看到,一个类对应一个class对象,无论用什么方式获取;

获取构造方法

1.Constructor<?>[] getConstructors()
返回包含一个数组 Constructor对象反射由此表示的类的所有公共构造 类对象。
2.Constructor< T > getDeclaredConstructors()
返回一个 Constructor对象,该对象反映 Constructor对象表示的类或接口的指定 类函数。
3.Constructor<?>[] getDeclaredConstructor()
返回一个私有构造方法 。
4.Constructor getConstructor()
返回一个 Constructor对象,该对象反映 Constructor对象表示的类的指定的公共 类函数。


import java.lang.reflect.Constructor;

/*
*  获取构造方法
* */
public class Demo02 {
 //   private static Object String;

    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {

        Class cls=Class.forName("反射.Person");
       Constructor<Person> cs= cls.getConstructor();
        System.out.println(cs);
        System.out.println("===========================");
        Constructor<Person>[] csn=cls.getConstructors();
        for(Constructor<Person> s:csn){
            System.out.println(s);
        }
        System.out.println("===========================");
        Constructor<Person>  cs2=cls.getDeclaredConstructor(int.class,String.class);
        System.out.println(cs2);
        System.out.println("===========================");
        Constructor<Person>[] cs3=cls.getDeclaredConstructors();
        for (int i = 0; i < cs3.length; i++) {
            Constructor<Person> personConstructor = cs3[i];
            System.out.println(personConstructor);
        }
    }
}

控制台输出

获取成员变量

1.Field getDeclaredField(String name)
返回一个 Field对象,它反映此表示的类或接口的指定已声明字段 类对象。
2.Field[] getDeclaredFields()
返回的数组 Field对象反映此表示的类或接口声明的所有字段 类对象。
3.Field getField(String name)
返回一个 Field对象,它反映此表示的类或接口的指定公共成员字段 类对象。
4.Field[] getFields()
返回包含一个数组 Field对象反射由此表示的类或接口的所有可访问的公共字段 类对象。

import java.lang.reflect.Field;

/*
获得成员变量
 */
public class Demo03 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
        Class cls=Class.forName("反射.Person");
        Field  f1=cls.getDeclaredField("age");
        System.out.println("字段名为“age”的私有变量"+f1);
        System.out.println("==========================");
        Field[] f2=cls.getDeclaredFields();
        System.out.println("全部的成员变量");
        for (Field field : f2) {
            System.out.println(field);
        }
        System.out.println("==========================");
         Field  f3=cls.getField("a");
        System.out.println("公共成员变量"+f3);
        System.out.println("==========================");
        Field[] f4=cls.getFields();
        System.out.println("所有公共的成员变量");
        for (Field field : f4) {
            System.out.println(field);

        }
    }
}

控制台输出
在这里插入图片描述

获取成员方法

1.方法 getDeclaredMethod(String name, 类<?>… parameterTypes)
返回一个 方法对象,它反映此表示的类或接口的指定声明的方法 类对象。
2.方法[] getDeclaredMethods()
返回包含一个数组 方法对象反射的类或接口的所有声明的方法,通过此表示 类对象,包括公共,保护,默认(包)访问和私有方法,但不包括继承的方法。
3.方法 getMethod(String name, 类<?>… parameterTypes)
返回一个 方法对象,它反映此表示的类或接口的指定公共成员方法 类对象。
4.方法[] getMethods()
返回包含一个数组 方法对象反射由此表示的类或接口的所有公共方法 类对象,包括那些由类或接口和那些从超类和超接口继承的声明。

import java.lang.reflect.Method;

/*
  获取成员方法
 */
public class Demo04 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
        Class cls=Class.forName("反射.Person");
        Method   mt1=cls.getMethod("setAge", int.class);
        System.out.println("获取名称为“setAge,参数类型为int的方法”"+mt1);
        System.out.println("========================");
        Method[] mt2=cls.getMethods();
        for (Method method : mt2) {
            System.out.println(method);
        }
        System.out.println("========================");
        Method mt3=cls.getDeclaredMethod("ABC");
        System.out.println("获取私有方法“ABC”"+mt3);
        System.out.println("========================");
        Method[] mt4=cls.getDeclaredMethods();
        System.out.println("获取所有成员方法");
        for (Method method : mt4) {
            System.out.println(method);
        }

    }
}

控制台输出
在这里插入图片描述

简易‘框架’

就是在不改动任意代码的情况下,这个”框架“可以实现任意类;
首先来一个配置文件

在这里插入代码片
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.Properties;

/*
 做一个最基本的‘框架‘
   框架思想
 */
public class Demo05 {
    public static void main(String[] args) throws Exception{
        Properties pro=new Properties();
        ClassLoader cl=Demo05.class.getClassLoader();
        InputStream peiZhiFile = cl.getResourceAsStream("反射.PeiZhiFile");
        pro.load(peiZhiFile);
        String className = pro.getProperty("className");
        String methodName = pro.getProperty("methodName");
        Class cls=Class.forName(className);
        
        Method mt=cls.getMethod(methodName);
        mt.invoke(new Object());
    }
}

注解

定义

(Annotation);如果说’注释‘是写给程序员看的,那么‘注解’就是写给程序看的;
注解是程序中的一种特殊标记。通过注解,编译器可以了解到该部分程序被保留的阶段、赋值传递等特殊用途。

JDK中预定义的注解

@Override
表示该方法为重写方法;
@SuppressWarnings()
压制(忽视)警告;
@Deprecated
表示该方法已过时


public class Demo02 extends T1{
    @Deprecated
    public void show1(){

    }
    public void show2(){
    }
     @Override
     public void add(){

     }
     @SuppressWarnings("true")
     public void show3(){
         new Demo02().show1();
     }
    public static void main(String[] args) {
    }
}

自定义注解

注解的本质

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

可以看出注解的本质是一个接口;所以它的基本格式就是

public @interface MyAnnotation{
    }

元注解
用于描述注解的注解。

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
=============
这两行就是元注解

1.@Retention
表示注解可保留的阶段;

  • RententionPolicy.SOURCE:将保留至源码阶段。编译时将隐藏
  • RententionPolicy.CLASS:将保留至class文件阶段。但对运行对虚拟机隐藏
  • Rentention.RUNTIME:可保留至运行时。【一般都保留到运行时】
    2.@Document
    表示注解将会被计入API文档;
    3.@Inherited
    表示注解会被自动继承;
    4.@Target
    表示被修饰的注解将要被作用的位置。它有三个常见取值
    ElementType.TYPE:可作用于类
    ElementType.FIELD:可作用于成员变量
    ElementType.METHOD:可作用于成员方法
    在这里插入图片描述
    属性
    注解中的属性指的是接口中的抽象方法;为什么被称为属性呢?因为每一个方法在注解中都需要赋一个值。
    属性支持的返回类型有
    1.所有基本数据类型(int,float,boolean,byte,double,char,long,short)
    2.String类型
    3.Class类型
    4.enum类型
    5.Annotation类型
    6.以上所有类型的数组
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
public @interface MyAnnot {
    public int show1() ;
    //基本类型
   String show2()default "";
    //String
    Person show3()default Person.p1;
    //枚举
    MyAnnot2 show4();
    //注解
    String[] show5();
    //以上类型的数组


}

值得注意的是,在上面的属性没有被赋默认值的,在使用注解时要赋值;

public class Demo03 {
    @MyAnnot(show1 = 12,show4 = @MyAnnot2,show5 = {"3","3"})
    public void add(){
    }
}

程序中使用注解

可用来替换配置文件
这样我们就只需要修改注解,即可调用任意对象的任意方法了;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
@MyAnn(className ="Annotation.框架.Person",Method = "eat")
public class MyTest {
    public static void main(String[] args) throws  Exception{
        Class<MyTest> cls=MyTest.class;
        MyAnn at=cls.getAnnotation(MyAnn.class);
        String s=at.className();
        String method=at.Method();
        System.out.println(s);
        System.out.println(method);
        /
        Class cls1=Class.forName(s);
        Object obj=cls1.newInstance();
        Method mt=cls1.getMethod(method);
        mt.invoke(obj);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

高冷小伙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值