java学习--day25(反射)

文章目录

      • 今天的内容
      • 1.反射
        • 1.1获取Class对象
        • 1.2获取Constructor对象
        • 1.3获取Method对象
        • 1.4获取Field对象

今天的内容

1.反射【重点】

1.反射

反射很重要,咱们以后进行封装的时候都有必要书写反射,让咱们的代码具有更强普适性

Java反射是在动态的获取类, 类属性, 类方法, 类构造方法等内部一些类的信息。

反射本质就是反着来。

平常获取类 new 一个对象,现在可以通过反射来获取。

package com.qfedu.a_reflect;import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;public class Demo1 {public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {//想创建一个对象,直接newPerson person = new Person();//今天再学一种方式 使用反射的方式获取一个类的对象//java执行原理:先编译 后执行//编译之后的文件叫 Person.class  编// 译之后所有东西(类的属性,类的构造方法,类的成年成员方法)//都在person.class文件中,这个文件变成了一个类对象了//personClasss里卖弄有类的所有的信息Class<Person> personClass = Person.class;//getConstructor获得无参构造方法//Constructor  把无参构造方法封装给以一个对象Constructor<Person> constructor = personClass.getConstructor(null);//要无参构造干嘛?可以通过构造方法创建对象!!!Person person1 = constructor.newInstance(null);}public static void test(Person p) {}public static void test(Class cls) {}
}
从数据库里面查数据,但是查出来的数据要赋值一个类
new admin ();
new goods();
new order();
三个类对应这数据库里面这三张表
admin表:name   pwd狗蛋	  123
goods表:name   price汽车    78.9
order:name   status汽车    已付款
class BasweDao {
public List<T>  query (Class cls) {获取了name pwd  price   status值已经获取出来//得把这些值赋值给实体类//Admin admin = new Admin();//只能对admin赋值了,其他类不能赋值,这就不叫封装了,封装的目的是具有普适性Constructor<T> cst = cls.getConstructor(null);T t = cst.newInstance(null);}
}
Admin.class
query(Admin.class);
query(Goods.class);
query(Order.class);
1.1获取Class对象

为啥要获取Class对象?因为有了class对象才能找关于类的属性,方法 , 构造方法

Java可以将.java文件编译成.class文件,这个.calss文件中包含了原始文件中的所有的信息

.class文件会被类加载器加载到虚拟机中,可以通过.class文件获取原始类中的所有的信息

随之产生一个Class类对象。将Person.class变成了一个Class对象了

获取一个类的Class对象有三种方式:

package com.qfedu.b_class;import com.qfedu.a_reflect.Person;public class Demo1 {public static void main(String[] args) throws ClassNotFoundException {//第一种获取class对象方式//com.qfedu.a_reflect.Person 类全限定名Class<?> aClass = Class.forName("com.qfedu.a_reflect.Person");System.out.println(aClass);//第二种方式Class<Person> personClass = Person.class;System.out.println(personClass);//第三种方式Class<? extends Person> aClass1 = new Person().getClass();System.out.println(aClass1);}
}

为啥要获取一个类的字节码文件对象,因为我要获取字节码文件下面的 构造方法 方法 属性 等信息

1.2获取Constructor对象

和一个类中的构造方法有关系。构造方法类对象

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

以上的方法都是Class对象调用的

下面这个方法是Construct对象调用的

TnewInstance(Object... initargs)使用此 Constructor对象表示的构造函数,使用指定的初始化参数来创建和初始化构造函数的声明类的新实例。
package com.qfedu.c_constructor;import com.qfedu.a_reflect.Person;import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;public class Demo1 {public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {//1.获取一个类对应的class对象Class<Person> personClass = Person.class;//2.再拿class对象获取构造方法对象Constructor<?>[] constructors = personClass.getConstructors();System.out.println(constructors);//内存地址for (Constructor<?> constructor : constructors) {System.out.println(constructor);}System.out.println("-========");//3.获取一个类所有的构造方法对象Constructor<?>[] declaredConstructors = personClass.getDeclaredConstructors();for (Constructor<?> declaredConstructor : declaredConstructors) {System.out.println(declaredConstructor);}//4.获取单个的constructor对象//参数是个null  就证明获取的是无参的Constructor<Person> constructor = personClass.getConstructor(null);System.out.println(constructor);//Person();System.out.println("----------");//5获取带有字符串类型的有参构造方法//参数Class 对象 怎么将String转为Class对象Constructor<Person> constructor1 = personClass.getConstructor(String.class);System.out.println(constructor1);//Person(String name)Constructor<Person> constructor2 = personClass.getConstructor(String.class, int.class);System.out.println(constructor2);//Person(String name)//不能的!!!
//        Constructor<Person> constructor3 = personClass.getConstructor(int.class);
//        System.out.println(constructor3);//Person(int name)//6.获取私有化的构造方法Constructor<Person> declaredConstructor = personClass.getDeclaredConstructor(int.class);System.out.println(declaredConstructor);//newInstance(Object... parameter)  是Constructor对象调用的//不是calss对象调用的  通过构造方法对象实例化一个对象出来Person person = constructor.newInstance(null);System.out.println(person);//如果有参的构造方法 有参构造方法可以传值Person person1 = constructor1.newInstance("狗蛋");System.out.println(person1);Person person2 = constructor2.newInstance("老王", 18);System.out.println(person2);}
}

只用getConstructor(Class…parameterType);

newInstance(Object… initargs);

一个类下面有构造方法 方法 属性

1.3获取Method对象
Method[]getMethods()获取当前类或者父类的公开的所有的方法
Method[]getDeclaredMethods()获取当前类所有的方法,但是不能获取父类的方案
MethodgetMethod(String name, 类<?>... parameterTypes)返回一个 方法对象,它反映此表示的类或接口的指定公共成
MethodgetDeclaredMethod(String name, 类<?>... parameterTypes)返回一个 方法对象,它反映此表示的类或接口的指定声明的方法 对象。

学一个Method下面的方法

Objectinvoke(Object obj, Object… args)在具有指定参数的 方法对象上调用此 方法对象
package com.qfedu.d_method;import com.qfedu.a_reflect.Person;import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;public class Demo1 {public static void main(String[] args) throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {Class<Person> personClass = Person.class;//通过class对象获取一个类下面方法对象Method//打印的本类公开的方法和父类的方法Method[] methods = personClass.getMethods();for (Method method : methods) {System.out.println(method);}System.out.println("==========");//获取本类的所有的方法Method[] declaredMethods = personClass.getDeclaredMethods();for (Method declaredMethod : declaredMethods) {System.out.println(declaredMethod);}//获取一个方法  第一个参数  String方法的名字,第二个参数 方法的参数的数据类型Method eat = personClass.getMethod("eat", null);System.out.println(eat);//无参的eat方法Method eat1 = personClass.getMethod("eat", String.class);System.out.println(eat1);//有参的eat方法 参数string类型的数据//私有话的方法getDeclaredMethodMethod sleep = personClass.getDeclaredMethod("sleep", null);System.out.println(sleep);//方法对象获取以后干嘛?//方法要被调用  使用Method对象调用invoke这个方法//第一个Object 是你得告诉我在那个对象下面调用//Object... args  是方法的参数的实参!!!//invoke(Object obj, Object... args)在具有指定参数的 `方法`对象上调用此 `方法`对象Person person = personClass.newInstance();//方法对象自己执行方法eat.invoke(person, null);eat1.invoke(person, "狗子");//证明权限不够!!!咋办 接近不了//can not access a member//咋办,让它接近就可以啦。 暴力反射sleep.setAccessible(true);sleep.invoke(person, null);}
}

总结:

getMethod(string name, class<?> ... parameterType);
调用
invoke(Object obj, Object....paramter)

上午的内容

1.获取三种方式Class.forName("包名+ 类名");类.class对象.getClass()
2.获取构造方法对象class对象.getConstructor();construct对象.newInstance();根据构造方法实例化对象
3.获取方法对象class对象.getMethod(String name, Class<?> ...parameterType);method对象.invoke(Object obj, Object... initargs);

类下面还有成员变量

Field

1.4获取Field对象
package com.qfedu.e_field;import com.qfedu.a_reflect.Person;import java.lang.reflect.Field;public class Demo1 {public static void main(String[] args) throws NoSuchFieldException, InstantiationException, IllegalAccessException {//属性是在一个类下面,也要Class对象获取属性对象Class<Person> personClass = Person.class;//getFields获取公开的属性Field[] fields = personClass.getFields();for (Field field : fields) {System.out.println(field);}System.out.println("===========");Field[] declaredFields = personClass.getDeclaredFields();for (Field declaredField : declaredFields) {System.out.println(declaredField);}//获取一个属性对象 参数是属性的名字Field name = personClass.getField("name");System.out.println(name);//能不能使用getField方法获取私有的属性或者默认的属性?不能!!
//        Field age = personClass.getField("age");
//        System.out.println(age);Field age = personClass.getDeclaredField("age");System.out.println(age);Field sex = personClass.getDeclaredField("sex");System.out.println(sex);//属性对象可以获取的,获取以后干嘛?属性是用来赋值的//对象属性进行赋值  set方法Person person = personClass.newInstance();name.set(person, "狗子");System.out.println(person);//暴力反射age.setAccessible(true);age.set(person, 12);System.out.println(person);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/100391.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

粘性文本整页滚动效果

效果展示 CSS 知识点 background 相关属性综合运用position 属性的 sticky 值运用scroll-behavior 属性运用scroll-snap-type 属性运用scroll-snap-align 属性运用 整体页面效果实现 <div class"container"><!-- 第一屏 --><div class"sec&qu…

一致性哈希算法

普通取模算法 假设我们有三台缓存服务器&#xff0c;用于缓存图片&#xff0c;我们为这三台缓存服务器编号为 0号、1号、2号&#xff0c;现在有3万张图片需要缓存&#xff0c;我们希望这些图片被均匀的缓存到这3台服务器上&#xff0c;以便它们能够分摊缓存的压力。也就是说&a…

JAVA编程题-求矩阵螺旋值

螺旋类 package entity; /*** 打印数组螺旋值类*/ public class Spiral { // 数组行private int row; // 数组列private int col; // 行列数private int size; // 当前行索引private int rowIndex; // 当前列索引private int colIndex; // 行开始索引private int rowStart; //…

Docker---cgroups资源限制

目录 一、cpu资源控制 1、 设置cpu使用率上限 2、设置cpu资源占用比&#xff08;设置多个容器时才有效&#xff09; 3、设置容器绑定指定的CPU 三、内存资源控制 四、磁盘IO配额控制 1、限制Block IO 2、限制bps和iops进行限制 一、cpu资源控制 cgroups是一个非常强大的…

【TypeScript】阮一峰TypeScript教程笔记:基本用法、any 类型等、类型系统

是阮一峰 TypeScript 教程的笔记。笔记目录与教程目录一致。笔记不全&#xff0c;仅作自己学习使用&#xff0c;完整学习请看&#xff1a;阮一峰 TypeScript 教程或TypeScript官方文档。 文章目录 简介基本用法any 类型&#xff0c;unknown 类型&#xff0c;never 类型any 类型…

web基础以及http协议

web基础&#xff0c;http协议 域名&#xff1a;www.88886.co DNS解析 静态页面 动态页面 DNS域名&#xff1a; 网络上的通信都是基于IP通信模式&#xff1a;TCP/IP TCP建立连接和断开连接&#xff0c;都是要双方进行确认的 建立连接&#xff1a;三次握手 断开连接&#x…

Spring源码解析(十二):TransactionInterceptor事务拦截器

Spring源码系列文章 Spring源码解析(一)&#xff1a;环境搭建 Spring源码解析(二)&#xff1a;bean容器的创建、默认后置处理器、扫描包路径bean Spring源码解析(三)&#xff1a;bean容器的刷新 Spring源码解析(四)&#xff1a;单例bean的创建流程 Spring源码解析(五)&…

dockerfile lnmp 搭建wordpress、docker-compose搭建wordpress

-----------------安装 Docker--------------------------- 目前 Docker 只能支持 64 位系统。systemctl stop firewalld.service setenforce 0#安装依赖包 yum install -y yum-utils device-mapper-persistent-data lvm2 --------------------------------------------------…

NoSQL之Redis 主从复制配置详解及哨兵模式

目录 1 Redis 主从复制 1.1 主从复制的作用 1.2 主从复制流程 2 搭建Redis 主从复制 2.1 安装 Redis 2.2 修改 Redis 配置文件&#xff08;Master节点操作&#xff09; 2.3 修改 Redis 配置文件&#xff08;Slave节点操作&#xff09; 2.4 验证主从效果 3 Redis 哨兵模…

揭秘 Go 中的 new() 和 make() 函数

Go&#xff08;或 Golang&#xff09;是一种现代、静态类型、编译型的编程语言&#xff0c;专为构建可扩展、并发和高效的软件而设计。它提供了各种内置的函数和特性&#xff0c;帮助开发人员编写简洁高效的代码。其中包括 new() 和 make() 函数&#xff0c;这两个函数乍看起来…

一个命令让redis服务端所有信息无所遁形~(收藏吃灰系列)

Redis服务器是一个事件驱动程序&#xff0c;它主要处理两类事件&#xff1a;文件事件和时间事件。这些事件的处理和Redis命令的执行密切相关。下面我将以Redis服务端命令为切入点&#xff0c;深入解析其工作原理和重要性。 首先&#xff0c;我们先了解Redis服务端有哪些命令。…

【JavaScript】浅拷贝与深拷贝

引言 浅拷贝、深拷贝是对引用类型而言的。 引用类型的变量对应一个栈区地址&#xff0c;这个栈区地址处存储的值是存放的真正的数据的堆区地址。 基本数据类型的变量也对应一个栈区地址&#xff0c;但是该地址存储的是其真正的值。 let a b发生了什么&#xff1f; let obj…

this关键字在不同上下文中的值是如何确定的?

聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 欢迎来到前端入门之旅&#xff01;感兴趣的可以订阅本专栏哦&#xff01;这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发…

vsftpd使用

安装vsftpd yum install vsftpd -y版本&#xff1a;3.0.2三种访问方式&#xff1a;匿名访问、本地用户访问、虚拟用户访问 虚拟用户访问配置 # 1. 配置虚拟用户 cd /etc/vsftpd mv vsftpd.conf vsftpd.conf.bak grep -v "#" vsftpd.conf.bak > vsftpd.conf ech…

利用互斥锁实现多个线程写一个文件

代码 #include <stdio.h> #include <pthread.h> #include <string.h> #include <unistd.h>FILE *fp;//线程函数1 void *wrfunc1(void *arg); //线程函数2 void *wrfunc2(void *arg); //线程函数3 void *wrfunc3(void *arg);//静态创建互斥锁 pthread_…

Python爬虫技术系列-03requests库案例-完善

Python爬虫技术系列-03requests库案例 参考1 Requests基本使用1.1 Requests库安装与使用1.1.1 Requests库安装1.1.2 Rrequests库介绍1.1.3 使用Requests一般分为三个步骤1.1.4 requests的公共方法 2 Requests库使用案例2.1 GET请求携带参数和headers2.2 POST请求&#xff0c;写…

(8)SpringMVC中的视图类型及其特点,以及视图控制器view-controller的配置

SpringMVC的视图 转发和重定向的区别及其原理,参考文章 视图类型及特点 视图的作用就是将Model中的数据渲染到页面上并展示给用户,SpringMVC中视图对应的View接口有三种实现类对应三种视图解析器 默认有转发视图InternalResourceView和重定向视图RedirectView以及Thymeleaf…

edu 156 div2 c

#include <bits/stdc.h> using namespace std; using ll long long; void solve(){string s;cin>>s;//s s;ll t;cin>>t;//t--;ll pos,k;ll len 0;for(int i 0 ; i < s.length() ; i){if(len s.length() - i > t){pos t - len;//第几个字符k i;…

【接口干货】热门、免费api集合

手机号码归属地&#xff1a;可根据手机号码查询其省市区、运营商区号行政区划代码等信息。 上亿条数据囊括最新的170、166、147等号段&#xff0c;更新及时、准确度高。 短信验证码&#xff1a;可用于登录、注册、找回密码、支付认证等等应用场景。支持三大运营商&#xff0c;…

Cpolar内网穿透工具在windows和Linux上具体使用

Cpolar内网穿透工具在windows和Linux上具体使用 一、Linux上部署的项目通过内网穿透实现外网访问项目二、Windows上部署的项目通过内网穿透实现外网访问项目 一、Linux上部署的项目通过内网穿透实现外网访问项目 一个免费的内网穿透方式&#xff0c;简单方便。 网址&#xff1a…