JavaWeb---反射

news/2024/5/19 4:00:58 标签: 反射
User user = new User(23,"唐嫣");
反射field.set(user,"柳岩")可以将user的值改变为23,柳岩

Map<String,String[]> map = getParameterMap();
数组直接打印得到的是哈希地址值,集合是{...}的样式

Class.forName("全类名");
全类名不是路径,:全类名写的地址叫classPath,它既不是相对路径,也不是绝对路径,而是类路径
通常从包开始写起,如果不知道包是哪里,就找最上面的关键字package
 package test.tt.com.ithei.study-->test.tt.com.ithei.study.TestPath;
注意:前面没有/,不是相对路径的省略写法,全类名跟绝对路径相对路径无关
Class cla = method.getDeclaringClass(); //获得method的Class类对象

自定义注解测试

1.自定义注解
@Target({ElementType.TYPE,ElementType.METHOD,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation{
    String name();
    Integer age() default 20;
}

2.注解测试
public class TestAnnotation{
	@MyAnnotation(name = "张三")
	private String name;
	
    public static void main(String[] args){
    	Class clazz = TestAnnotation.class;
    	Field nameField = clazz.getDeclaredField("name");
    	MyAnnotation myAnnotation = nameField.getAnnotation(MyAnnotation.class);
    	String name = myAnnotation.name();
    	Integer age = myAnnotation.age();
    }
}




1. Junit单元测试

   - 标准的的单元测试方法

     ```java
     public class 被测试的类名Test{
         @Test(maven中最好使用4.12版本)
         public void test被测试的方法名(){
             //测试代码可以是sout输出,也可以是断言;
             Assert.assertEquals(期望值,实际值);
         }
     }
     ```

     - 注意:单元测试方法可以像main方法一样单独运行,格式必须和上面一致。使用@Test注解需要导入Junit4单元测试库(**alt+enter提示**2. 反射

   - **java类的执行过程:**一个普通的java文件先被编译成.class文件,jvm加载.class文件到内存中,形成一个Class对象,这个对象中封装了java类的所有信息**(成员变量、构造方法、成员方法)**- **反射**将类的各个组成部分封装为其他对象,这就是反射机制,通俗的说就是通过Class对象操作java类的各个部分**(创建对象、给属性赋值和获取值、调用方法)**


   - **反射的实现思路(重要):**

     1. **获取Class对象(3种方式)**

        ```java
        1. Class.forName("全类名"):将字节码文件加载进内存,返回Class对象
        2. 类名.class:通过类名的属性class获取
        3. 对象名.getClass()getClass()方法在Object类中定义着。
        ```

     2. **获取 Field对象 / Constructor对象 / Method对象**

        1. 方法特征:带s表示获取多个;带declared表示获取任意类型,否则只能获取public修饰的对象;

     3. **操作Field对象 / Constructor对象 / Method对象**

        1. 操作Field对象:

           通过set(Object obj, Object value)方法赋值:给obj对象的field属性设置value值

           通过get(Object obj)方法获取值:获取obj对象的filed属性值

           **注意:如果filed表示的属性是非public类型,那么在set()/get()之前通过setAccessible(true)暴力反射**

        2. 操作Constructor对象

           通过T newInstance(Object... initargs)实例化一个对象

           **注意:如果Constructor表示的构造是非public类型,那么在实例化之前通过	setAccessible(true)暴力反射**

        3. 操作Method对象

           通过Object invoke(Object obj, Object... args)方法执行Method表示的方式;

           ​	Object obj:表示执行obj对象的Method对应方法;

           ​	Object... args: 执行该方法需要传递的参数

           ​	返回值:invoke方法的返回值就是调用method表示方法的返回值;

           **注意:如果Method表示的方法是非public类型,那么在invoke之前通过	setAccessible(true)暴力反射**

3. 注解

   自定义一个标准的注解

   ```java
   @Target({ElementType.TYPE,ElementType.METHOD,ElementType.FIELD})//规定自定义注解使用的位置
   @Retention(RetentionPolicy.RUNTIME)//自定义注解的作用范围,一般是RUNTIME阶段;
   public @interface 注解名称{
       String name();
       int age() default 18;
       //...
   }
  • 注解在开发中的作用:框架中定义的注解居多,一般是用来替换配置文件
  • 注意:注解对象只能在反射过程中通过Class、Field、Constructor、Method对象来获取;

Junit单元测试

* 测试分类:
	1. 黑盒测试:不需要写代码,给输入值,看程序是否能够输出期望的值。
	2. 白盒测试:需要写代码的。关注程序具体的执行流程。

* Junit使用:白盒测试
	* 步骤:
		1. 定义一个测试类(测试用例)
			* 建议:
				* 测试类名:被测试的类名Test		
				* 包名:xxx.xxx.xx.test		

		2. 定义测试方法:可以独立运行
			* 建议:
				* 方法名:test测试的方法名		testAdd()  
				* 返回值:void
				* 参数列表:空参

		3. 给方法加@Test
		4. 导入junit4依赖环境

	* 判定结果:
		* 红色:失败
		* 绿色:成功
		* 一般我们会使用断言操作来处理结果
			* Assert.assertEquals(期望的结果,运算的结果);

	* 补充:
		* @Before:
			* 修饰的方法会在测试方法之前被自动执行
		* @After:
			* 修饰的方法会在测试方法执行之后自动被执行

反射:框架设计的灵魂

* 框架:半成品软件。可以在框架的基础上进行软件开发,简化编码
* 反射:将类的各个组成部分封装为其他对象,这就是反射机制
	* 好处:
		1. 可以在程序运行过程中,操作这些对象。
		2. 可以解耦,提高程序的可扩展性。


* 获取Class对象的方式:
	1. Class.forName("全类名"):将字节码文件加载进内存,返回Class对象
	全类名从包名称开始写起,test.pro.propeties
	Source源代码阶段
		* 多用于配置文件,将类名定义在配置文件中。读取文件,加载类
	2. 类名.class:通过类名的属性class获取
	Class类对象阶段
		* 多用于参数的传递
	3. 对象.getClass():getClass()方法在Object类中定义着。
	Runtime运行时阶段
		* 多用于对象的获取字节码的方式

	* 结论:
		同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取的Class对象都是同一个。


* Class对象功能:
	* 获取功能:
		1. 获取成员变量们
			* Field[] getFields() :获取所有public修饰的成员变量
			* Field getField(String name)   获取指定名称的 public修饰的成员变量

			* Field[] getDeclaredFields()  获取所有的成员变量,不考虑修饰符
			* Field getDeclaredField(String name)  
		2. 获取构造方法们
			* Constructor<?>[] getConstructors()  
			* Constructor<T> getConstructor(类<?>... parameterTypes)  
			
			* Constructor<?>[] getDeclaredConstructors() 
			* Constructor<T> getDeclaredConstructor(类<?>... parameterTypes)  
			eg: cla.getDeclaredConstructor(int.class,String.class);
		 
		3. 获取成员方法们:
			* Method[] getMethods()  
			* Method getMethod(String name, 类<?>... parameterTypes)  

			* Method[] getDeclaredMethods()  
			* Method getDeclaredMethod(String name, 类<?>... parameterTypes)  
			eg: cla.getDeclaredMethod(add,int.class,int.class);
		4. 获取全类名	
			* String getName()  


* Field:成员变量
	* 操作:
		1. 设置值
			* void set(Object obj, Object value)  
		2. 获取值
			* Object get(Object obj) 

		3. 忽略访问权限修饰符的安全检查,如果field是非public修饰的,在使用get/set之前,要暴力反射
			* field.setAccessible(true):暴力反射



* Constructor:构造方法
	* 创建对象:
		* T newInstance(Object... initargs)  
		constructor.newInstance(23,"你好");
		* 如果使用空参数构造方法创建对象,操作可以简化:class对象的newInstance()方法
		cla.newInstance();


* Method:方法对象
	* 执行方法:
		* Object invoke(Object obj, Object... args)  
		invoke的返回值就是调用method所代表的方法的返回值
	* 获取方法名称:
		* String getName:获取方法名

注解:

* 概念:说明程序的。给计算机看的
* 注释:用文字描述程序的。给程序员看的

* 定义:注解(Annotation),也叫元数据。一种代码级别的说明。它是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。
* 概念描述:
	* JDK1.5之后的新特性
	* 说明程序的
	* 使用注解:@注解名称

​ * 作用分类:
①编写文档:通过代码里标识的注解生成文档【生成文档doc文档】
②代码分析:通过代码里标识的注解对代码进行分析【使用反射
③编译检查:通过代码里标识的注解让编译器能够实现基本的编译检查【Override】

* JDK中预定义的一些注解
	* @Override	:检测被该注解标注的方法是否是继承自父类(接口)的
	* @Deprecated:该注解标注的内容,表示已过时
	* @SuppressWarnings:压制警告
		* 一般传递参数all  @SuppressWarnings("ALL")

* 自定义注解
	* 格式:
		元注解
		public @interface 注解名称{
			属性列表;
		}

	* 本质:注解本质上就是一个接口,该接口默认继承Annotation接口
		* public interface MyAnno extends java.lang.annotation.Annotation {}

	* 属性:接口中的抽象方法
		* 要求:
			1. 属性的返回值类型有下列取值
				* 基本数据类型
				* String
				* 枚举
				* 注解
				* 以上类型的数组

			2. 定义了属性,在使用时需要给属性赋值
				1. 如果定义属性时,使用default关键字给属性默认初始化值,则使用注解时,可以不进行属性的赋值。  public abstract int age() default 18;
				2. 如果只有一个属性需要赋值,并且属性的名称是value,则value可以省略,直接定义值即可。
				3. 数组赋值时,值使用{}包裹。如果数组中只有一个值,则{}可以省略
	
	* 元注解:用于描述注解的注解
		* @Target:描述注解能够作用的位置 
        @Target({ElementType.TYPE,ElementType.METHOD,ElementType.FIELD})
			* ElementType取值:
				* TYPE:可以作用于类上  
				* METHOD:可以作用于方法上
				* FIELD:可以作用于成员变量上
		* @Retention:描述注解被保留的阶段
			* @Retention(RetentionPolicy.RUNTIME):当前被描述的注解,会保留到class字节码文件中,并被JVM读取到
		* @Documented:描述注解是否被抽取到api文档中
		* @Inherited:描述注解是否被子类继承


* 在程序使用(解析)注解:获取注解中定义的属性值
	1. 获取注解定义的位置的对象  (Class,Method,Field)
	2. 获取指定的注解
		* getAnnotation(Class)
		//其实就是在内存中生成了一个该注解接口的子类实现对象

	            public class ProImpl implements Pro{
	                public String className(){
	                    return "cn.itcast.annotation.Demo1";
	                }
	                public String methodName(){
	                    return "show";
	                }
	            }
	3. 调用注解中的抽象方法获取配置的属性值

http://www.niftyadmin.cn/n/1490693.html

相关文章

java面试总结(十)—— 常用技术介绍

对于面试&#xff0c;面试官总会对我们简历上的项目经历涉及到一些技术进行询问&#xff0c;大多让我们介绍一下技术的用途、特点等等&#xff0c;本文就提供一些常用的技术的简介&#xff0c;如果大家有一些想分享的&#xff0c;可以留言&#xff0c;我在添加。 注&#xff1…

JavaWeb--MySQL约束

查看事务的提交方式: select autocommit;设置事务的提交方式: set autocommit 0/1 ; -- 0代表手动提交,1代表自动提交 limit 不能搭配 in使用 eg: select * from user where id in (select * from person limit 0,10) //错误写法 order by rand() 随机排序 eg:select * from …

JavaWeb--MySQL多表与事务

今日内容 多表关系&#xff08;理解&#xff09; 一对一&#xff1a;在任意一方添加外键指向另一方的主键&#xff0c;并且给外键字段添加unique约束&#xff1b;&#xff08;了解&#xff09; 一对多&#xff1a;在多的一方添加外键指向一的一方的主键&#xff1b; 多对多&…

SpringBoot实现一个项目多模块,多主启动模块,每个模块多环境配置文件

我们在日常开发过程中&#xff0c;在新建一个项目中&#xff0c;我们经常会将一个项目按照功能性、模块等将一个项目分成多个子项目&#xff0c;这些子项目都包含在主项目中。 对于Spring、SpringBoot中实现多模块化&#xff0c;网上有很多教程&#xff0c;这里就不在讲述了。 …

继承关系执行顺序

继承关系下静态代码块,非静态代码块,构造方法的执行顺序 public class Father{static{System.out.println("父类的静态代码块");}{System.out.println("父类的非静态代码块");}public Father(){System.out.println("父类的构造方法");} }public…

《Redis设计与实现》全面知识整理

最近在看Redis的实现原理&#xff0c;看到《Redis设计与实现》这本书&#xff0c;发现这本书对Redis的讲解可以说是很透彻了&#xff0c;不仅从Redis的设计方案以及其各种功能是如何实现的&#xff0c;均有很清晰的讲解 通过看这本书&#xff0c;能够很清晰的对Redis的整体结构…

一看就懂的IOC创建对象流程,以及循环依赖解决的三级缓存流程

这两天一直在看IOC容器在创建指定对象的流程&#xff0c;以及解决循环依赖的三级缓存流程&#xff0c;按照自己的理解画了个流程图&#xff0c;以及文字说明&#xff0c;如果有错误的地方欢迎指出&#xff1a;

JavaWeb-DataSource

注意:String sql "select * from user where name like ?";template.query(sql,"%李%");错误写法:String sql "select * from user where name like %?%";String sql "select * from user where name like ?";template.query(sq…