java进阶学习笔记

news2024/11/26 6:01:58

学习java深度学习,提升编程思维,适合掌握基础知识的工作者学习

  • 1.反射和代理
    • 1.1 概念介绍
    • 1.2应用场景
    • 1.3 反射-reflect
      • 1.3.1 获得类-Class
      • 1.3.2 获得类的字段-Field
      • 1.3.3 动态访问和修改对象实例的字段
      • 1.3.4 获得类方法-Method
      • 1.3.5 调用方法.invoke
      • 1.3.6 类实例化-构造函数Constructor
      • 1.3.7 instanceof
      • 1.3.8 利用反射来解析spring配置
    • 1.4 代理
      • 1.4.1 代理模式
      • 1.4.2 准备工作
      • 1.4.3 静态代理
      • 1.4.4 动态代理

1.反射和代理

1.1 概念介绍

在Java编程中,反射和代理是两个强大的特性,能够在运行时动态地操作和扩展类的行为。通过反射,我们可以在不知道类的具体信息的情况下操作类的属性和方法;而代理则允许我们创建一个代理类来拦截并增强目标对象的行为

1.2应用场景

像咱们平时大部分时候都是在写业务代码,很少会接触到直接使用反射机制的场景。
但是,这并不代表反射没有用。相反,正是因为反射,你才能这么轻松地使用各种框架。像 Spring/Spring Boot、MyBatis 等等框架中都大量使用了反射机制,掌握反射和代理机制,有利于我们了解这些框架的内核原理,提升编程思维

  • xml的bean配置的注入
  • AOP拦截
  • 数据库事务
  • springMVC
  • Java注解
  • 开发工具如IDEA,提供一个类的属性方法展示给我们智能快捷选择

这些内核都是反射和代理机制在其作用

1.3 反射-reflect

由于JVM为每个加载的class创建了对应的Class实例,并在实例中保存了该class的所有信息,包括类名、包名、父类、实现的接口、所有方法、字段等,因此,如果获取了某个Class实例,我们就可以通过这个Class实例获取到该实例对应的class的所有信息。这种通过Class实例获取class信息的方法称为反射(Reflection)。

我们正常得到一个对象实例是通过new方法创建对象;反射就是通过class来实现,
1.获得类class
2.获得类的字段属性和方法
3.获得类的实例对象
4.获得对方法的调用

准备工作

Food.java

public class Food {
    private Integer id;
    private  String name;
   // ....省略get set 等
}

1.3.1 获得类-Class

获得类有三种方式,看代码演示

类.class
对象.getClass();
Class.forName(“类名”)

 /***
     * @Description: 得到Class
     */
    @Test
    public void t1() throws ClassNotFoundException {
        Class cls=null;
        //1.通过类名直接获得
        cls= Food.class;
        //2.通过实例获得
        cls=new Food(1, "火锅").getClass();
        //3.通过路径+类名的字符串获得
        cls=Class.forName("com.jsoft.reflection.Food");
        printClassInfo(cls);


    }

    /***
     * @Description: 读取类的信息

     */
    static void printClassInfo(Class cls) {
        System.out.println("Class name: " + cls.getName());
        System.out.println("Simple name: " + cls.getSimpleName());
        if (cls.getPackage() != null) {
            System.out.println("Package name: " + cls.getPackage().getName());
        }
        System.out.println("is interface: " + cls.isInterface());
        System.out.println("is enum: " + cls.isEnum());
        System.out.println("is array: " + cls.isArray());
        System.out.println("is primitive: " + cls.isPrimitive());
    }

打印效果

Class name: com.jsoft.reflection.Food
Simple name: Food
Package name: com.jsoft.reflection
is interface: false
is enum: false
is array: false
is primitive: false

1.3.2 获得类的字段-Field

演示代码

public class Father  extends Man{
    private Integer age;
    public  String job;

}

public class Man{
    private Integer id;
    private String name;
    public String address;
    }

对任意的一个Object实例,只要我们获取了它的Class,就可以获取它的一切信息。
我们先看看如何通过Class实例获取字段信息。Class类提供了以下几个方法来获取字段:

方法说明
Field getField(name)根据字段名获取某个public的field(包括父类)
Field[] getFields()获取所有public的field(包括父类)
Field getDeclaredField(name)根据字段名获取当前类的某个field(不包括父类)
Field[] getDeclaredFields():获取当前类的所有field(不包括父类)

注意:
Declared修饰就只管当前类字段,和private、public无关
否则就包含父类的public

测试代码

 @Test
    public void t2() throws NoSuchFieldException {
       Class cls= Father.class;
       //1.得到当前类的所有字段,不包含父类
       Field[] fs=cls.getDeclaredFields();
        System.out.println("1.得到当前类的所有字段,不包含父类");
        for (Field f : fs) {
            printFeild(f);
        }
        //2.得到当前类某个字段
        System.out.println("2.得到当前类某个字段,不包含父类");
       Field f=cls.getDeclaredField("job");
        printFeild(f);

        //3.得到当前类及父类的所有public字段
        System.out.println("3.得到当前类及父类的所有public字段");
        fs=cls.getFields();
        for (Field f1 : fs) {
            printFeild(f);
        }

        //4.得到当前类及父类的public字段
        System.out.println("4.得到当前类及父类的public字段,如果是private,则要报错");
        f=cls.getField("address");
        printFeild(f);

    }

    /***
     * @Description: 打印字段信息
     */
    public  void printFeild(  Field f){
        System.out.println("//------------字段信息 start");
        System.out.println("字段名称:"+f.getName());
        System.out.println("字段类型:"+f.getType().getName());

        int m = f.getModifiers();
        System.out.println("field is final:"+Modifier.isFinal(m));; // true
        System.out.println("field is Public:"+Modifier.isPublic(m));; // true
        System.out.println("field is Protected:"+Modifier.isProtected(m));; // true
        System.out.println("field is Private:"+Modifier.isPrivate(m));; // true
        System.out.println("field is Static:"+Modifier.isStatic(m));; // true

        System.out.println("//------------字段信息 end");
    }

1.3.3 动态访问和修改对象实例的字段

我们可以通过一个对象对应的class去动态访问或修改对象的字段
Field.set(vo对象,修改值) //修改字段值
Feild.get(vo对象) //获得字段值
Feild.setAccessible(true); //私有字段,需要设置这个允许访问,否则报异常

  @Test
    public void t3() throws NoSuchFieldException, IllegalAccessException {
        Food food=new Food(1, "火锅");
        System.out.println("food.getName:"+food.getName());
        Class cls=food.getClass();
        Field f=cls.getDeclaredField("name");
        f.setAccessible(true); //不设置这个private 字段要抛出异常
        //通过field获得值
        Object name= f.get(food);
        System.out.println("name:"+name);
        //通过field设置值
        f.set(food, "西北风");
        System.out.println("name:"+food.getName());
    }

1.3.4 获得类方法-Method

方法说明
Method getMethod(name, Class…)获取某个public的Method(包括父类)
Method[] getMethods()获取所有public的Method(包括父类)
Method getDeclaredMethod(name, Class…)获取当前类的某个Method(不包括父类)
Method[] getDeclaredMethods():获取当前类的所有Method(不包括父类)

示例代码

@Data
public class Father  extends Man{
    private Integer age;
    public  String job;
   public  String play(int type){
        System.out.println("param value:"+type);
        return type+"";
    }

    public  String sleep(String type, Date date){
        System.out.println("param value type:"+type+";date:"+date);
        return type+"";
    }
    private  void self(){
        System.out.println("this is private method");
    }
	public void dd(){
        System.out.println("没有参数方法()");
    }


}

@Data
public class Man{
    private Integer id;
    private String name;
    public String address;

    @Override
    public Food eat() {

        return new Food(1,"火锅");
    }
}

测试代码

@Test
    public void t4() throws IllegalAccessException, NoSuchMethodException {
        Class cls= Father.class;
        System.out.println("1. 获取所有public的Method(包括父类)");
         Method[] methods=cls.getMethods();
        for (Method method : methods) {
            printMethod(method);
        }
        System.out.println("2. 获取某个public的Method(包括父类)");
        //第一个参数为方法名,第二参数是可变参数,传递方法的参数类型,如果无参数则不传递
        Method m= cls.getMethod("getName");
        printMethod(m);
        //方法有1个参数
        //注意int foat double这些基本类型对用的类是int.class,不是Integer.class
        m=cls.getMethod("play", int.class);
        printMethod(m);
        //方法有多个参数
        m=cls.getMethod("sleep", String.class, Date.class);
        printMethod(m);

        System.out.println("3. 获取当前类的的Method(不包括父类)");
        m= cls.getDeclaredMethod("getJob");
        printMethod(m);
        //私有方法也可以
        m= cls.getDeclaredMethod("self");
        //父类方法不可以,要报java.lang.NoSuchMethodException
        m= cls.getDeclaredMethod("eat");
        printMethod(m);

     printMethod(m);
    }

    public void printMethod(Method addMethod){
        System.out.println("---------方法名称: 【" + addMethod.getName()+"】---相关属性------------");
        System.out.println("修饰符: " + Modifier.toString(addMethod.getModifiers())); //public private等
        System.out.println("返回值: " + addMethod.getReturnType()); //返回值类型的class数组
        Class[] paramsCls= addMethod.getParameterTypes(); //参数值类型对应的class数组
    }

1.3.5 调用方法.invoke

我们可以用Method.invoke(vo,参数)来调用方法

代码

@Test
    public void t5() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Father father=new Father();
        Class cls= father.getClass();
        Method m=null;

        //无参无返回方法
        m=cls.getMethod("dd");
        m.invoke(father);

        //有参数,有返回值
        m=cls.getMethod("sleep", String.class,Date.class);
       String ret=(String)m.invoke(father, "1",new Date());
        System.out.println("返回值:"+ret);

        //private方法调用
        m=cls.getDeclaredMethod("self");
        //私有方法必须设置为m.setAccessible(true);
        m.setAccessible(true);
        m.invoke(father);

    }

jdk内置对象的方法调用的另外一种写法

  @Test
    public void t6() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
       String s="abcde";
       String sub=s.substring(0,2);
        System.out.println(sub);
        //通过类加载
        Class   cls=String.class;
        Method method=cls.getMethod("substring",int.class,int.class);
       sub=(String) method.invoke(s, 0,2);
        System.out.println(sub);

    }

Method m =Father.class.getMethod(“dd”);
m.invoke(new Father());

其实就相当于

Father f=new Father();
f.dd();

1.3.6 类实例化-构造函数Constructor

实例化对象有3中方法
1.我们都知道的new 对象Father father=new Father();
2.通过类class:newInstance
3.构造方法:Constructor

准备类

public class Const {
    private Integer id;
    private String name;

    public Const() {
        System.out.println("无参数构造方法");
    }

    public Const(Integer id, String name) {
        System.out.println("有参数构造方法");
        this.id = id;
        this.name = name;
    }
}

在很多框架里,我们为了足够的扩展,都通过配置来实现类的实例化

Class.newInstance()

  @Test
    public void t7() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
       Class cls =Class.forName("com.jsoft.reflection.Const");
        Const aConst = (Const) cls.newInstance();
        
    }

Class.newInstance()最大的问题是只能实例化无参的构造方法,如果我们把无参构造方法屏蔽掉,代码会出错,所以我们需要使用Constructor类来实现有参的构造方法

这里是引用一共有4种方法,全部都在Class类中:

  1. getConstructors():获取类中的公共方法
  2. getConstructor(Class[] params): 获取类的特定构造方法,params参数指定构造方法的参数类型
  3. getDeclaredConstructors(): 获取类中所有的构造方法(public、protected、default、private)
  4. getDeclaredConstructor(Class[] params): 获取类的特定构造方法,params参数指定构造方法的参数类型

代码示例

    @Test
    public void t8() throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        Class cls =Class.forName("com.jsoft.reflection.Const");
        //得到所有构造函数
        Constructor[] constructors=  cls.getConstructors();
        for (Constructor constructor : constructors) {
            System.out.println("修饰符: " + Modifier.toString(constructor.getModifiers()));
            System.out.println("构造函数名: " + constructor.getName());
            System.out.println("参数列表: " );
            Class[] cs= constructor.getParameterTypes();
            for (Class c : cs) {
                System.out.println(c.getName());
            }
        }

        //获得具体一个(无参)
        Constructor cst=cls.getConstructor();
        //newInstance实例化
        Const const1=(Const) cst.newInstance();

        //获得具体一个(有参)
         cst=cls.getConstructor(Integer.class,String.class);//传入构造函数的参数的类型
        //newInstance实例化
         const1=(Const) cst.newInstance(1,"蒋增奎");
    }

1.3.7 instanceof

instanceof是判断一个实例对象是不是一个类的实例,是则返回true
对象 instanceof 类

class Person{
}

class Teacher extends Person{
}

class Student extends Person{
}

测试

public class test01 {
    public static void main(String[] args) {
 
        Object obj = new Student(); // 主要看这个对象是什么类型与实例化的类名
        System.out.println(obj instanceof Student); // true
        System.out.println(obj instanceof Person); // true
        System.out.println(obj instanceof Object); // true
        System.out.println(obj instanceof String); // false
        System.out.println(obj instanceof Teacher); // false  无关系
        System.out.println("========================");

        Person person = new Student();
        System.out.println(person instanceof Person); // true
        System.out.println(person instanceof Object); // true
        // System.out.println(person instanceof String); // 编译错误
        System.out.println(person instanceof Teacher); // false 无关系

    }
}

1.3.8 利用反射来解析spring配置

<bean id="employee" class="com.jsoft.po.Employee">
    <property name="id" value="1" />
    <property name="name" value="蒋增奎" />
    <property name="deptId" value="001" />
</bean>

解析思路

1.用dom4j解析xml得到xml数据
2.创建类:Class cls=Class.forName(“Employee”);
3.创建对象:Employee obj=(Employee)cls.newInstance();
4.调用修改字段或者方法给字段注入值

1.4 代理

1.4.1 代理模式

代理模式是一种比较好理解的设计模式。简单来说就是 我们使用代理对象来代替对真实对象(real object)的访问,这样就可以在不修改原目标对象的前提下,提供额外的功能操作,扩展目标对象的功能。

代理模式的主要作用是扩展目标对象的功能,比如说在目标对象的某个方法执行前后你可以增加一些自定义的操作。

举个例子:
boy向girl求婚
(1)现代:boy和girl直接发生通信,girl迫不及待的同意了
(2)古代:boy不能直接和girl发生关系,需要通过媒婆,boy向媒婆发起请求,媒婆转告girl,gilr同意,媒婆觉得女孩如果同意,婚前应该收彩礼10万,婚后不能家暴,媒婆就是代理,在原始的反馈上增加了自己的要求,提升了框架的健壮性。
在这里插入图片描述
代理分为静态代理和动态代理两种类型

1.4.2 准备工作

public interface Love {

    /***
     * @Description: 结婚请求
     */
    public void marray();
}


/**
接口实现类
**/
public class LoveImpl implements Love {
    @Override
    public void marray() {
        System.out.println("我同意");
    }
}



1.4.3 静态代理

静态代理实现步骤:
1.定义一个接口及其实现类;
2.创建一个代理类同样实现这个接口
3.将目标对象注入进代理类,然后在代理类的对应方法调用目标类中的对应方法。这样的话,我们就可以通过代理类屏蔽对目标对象的访问,并且可以在目标方法执行前后做一些自己想做的事情。

代码:

//代理类要实现接口
public class LoveProxy implements Love {
    private Love target;//代理的接口
    /***
     * @Description: 构造方法注入代理的接口
     */
    public LoveProxy(Love love){
        target=love;
    }

    @Override
    public void marray(){
        System.out.println("要彩礼10万");
        target.marray();
        System.out.println("不能家暴");
    }

    
    public static void main(String[] args) {
        //实际应用:代理的应用
        Love love=new LoveImpl();
        LoveProxy proxy=new LoveProxy(love);
        proxy.marray();
        
    }


}

效果:在以前的需求上扩展了功能

要彩礼10万
我同意
不能家暴

1.4.4 动态代理

静态代理:通过手动编写代理类来实现,需要为每个目标对象编写一个代理类。
动态代理:通过Java提供的相关接口和类,在运行时动态生成代理类,无需手动编写代理类。

我们仍然先定义了接口,但是我们并不去编写实现类,而是直接通过JDK提供的一个Proxy.newProxyInstance()创建了一个Hello接口对象。这种没有实现类但是在运行期动态创建了一个接口对象的方式,我们称为动态代码。JDK提供的动态创建接口对象的方式,就叫动态代理。

动态代理三个重要的java类

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

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

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

相关文章

SpringBoot多模块项目下的包和组件扫描

问题阐述&#xff1a;为了简化项目代码&#xff0c;我们通常会使用多模块化代码进行开发&#xff0c;但是会出现如下问题&#xff1a;写代码时能够正常扫描或注入其他模块的Service&#xff0c;但是启动类一启动就报错Consider defining a bean of type com.xiaoqian.common.se…

【MATLAB第85期】基于MATLAB的2023年智能进化算法/元启发式算法合集(持续更新)

【MATLAB第85期】基于MATLAB的2023年智能进化算法/元启发式算法合集&#xff08;持续更新&#xff09; 1.海象进化算法&#xff08;Walrus Optimization Algorithm&#xff09; 作者&#xff1a;Pavel Trojovsk and Mohammad Dehghani 2.暴龙优化算法&#xff08;Tyrannosa…

java设计模式学习之【责任链模式】

文章目录 引言责任链模式简介定义与用途实现方式 使用场景优势与劣势在Spring框架中的应用日志示例代码地址 引言 在现实生活中&#xff0c;常常会遇到这样的场景&#xff1a;一个请求或命令需要经过多个层级的处理。例如&#xff0c;一个行政审批流程可能需要通过多个部门的审…

H5 cryptojs加密算法

1. cryptojs是什么&#xff1f; 有时候项目涉及到的敏感数据比较多&#xff0c;为了信息安全&#xff0c;我们常常需要对一些数据进行接口加密处理&#xff0c;如编码、将明文转化为暗文、加密比对、AES BASE64 算法加密等。 接下来我们就分别说一下 CryptoJS 常用的一些方法。…

爬虫是什么?起什么作用?

【爬虫】 如果把互联网比作一张大的蜘蛛网&#xff0c;数据便是放于蜘蛛网的各个节点&#xff0c;而爬虫就是一只小蜘蛛&#xff0c;沿着网络抓取自己得猎物&#xff08;数据&#xff09;。这种解释可能更容易理解&#xff0c;官网的&#xff0c;就是下面这个。 爬虫是一种自动…

jvm对象探究

hostpot虚拟机对象探究 jvm虚拟机创建对象的流程 ava虚拟机&#xff08;JVM&#xff09;创建对象的过程包括以下步骤&#xff1a; 类加载&#xff1a; 首先&#xff0c;JVM会检查对象的类是否已经被加载。如果该类还没有被加载&#xff0c;JVM会通过类加载器加载该类的字节码…

TCP服务器的演变过程:多进程实现一对多的TCP服务器

使用多进程实现一对多的TCP服务器 一、前言二、新增使用的fork()函数三、实现步骤四、完整代码五、TCP客户端5.1、自己实现一个TCP客户端5.2、Windows下可以使用NetAssist的网络助手工具 小结 一、前言 手把手教你从0开始编写TCP服务器程序&#xff0c;体验开局一块砖&#xf…

【C++】unordered_set/unordered_multiset/unordered_map/unordered_multimap

我们下面来学习C的另外两个容器&#xff1a;unordered_set和unordered_map 目录 一、unordered系列关联式容器 二、unordered_map 2.1 unordered_map的介绍 2.2 unordered_map的接口说明 2.2.1 unordered_map的构造 2.2.2 unordered_map的容量 2.2.3 unordered_map的迭…

室内设计品牌网站搭建的作用是什么

随着人们生活质量日益提升&#xff0c;对其自身的居住环境也有了较高要求&#xff0c;每个人审美不一样&#xff0c;无论自己居住的房屋还是公司办公/商场等场景都需要设计不同的内容&#xff0c;还有各种设施的摆放及类别等都有讲究&#xff0c;尤其对公司及商场等环境&#x…

动态规划算法练习题

45. 跳跃游戏 II 中等 2K 相关企业 给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。 每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说&#xff0c;如果你在 nums[i] 处&#xff0c;你可以跳转到任意 nums[i j] 处: 0 < j < nums[i] i j &…

EasyExcel 导出文件的格式化

阿里开源的这个库&#xff0c;让 Excel 导出不再复杂&#xff08;既要能写&#xff0c;还要写的好看&#xff09; 之前聊了 EasyExcel 的内容导出&#xff0c;本文主要说一下导出文件的格式化&#xff0c;格式化包括工作表/单元格样式和内容格式化。毕竟&#xff0c;有时候还是…

【leetcode21】合并两个有序链表Java代码讲解

12.22 21. 合并两个有序链表 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1&#xff1a; 输入&#xff1a;l1 [1,2,4], l2 [1,3,4] 输出&#xff1a;[1,1,2,3,4,4]示例 2&#xff1a; 输入&#xff1a;l1 [], l2…

Appium Server 启动失败常见原因及解决办法

Error: listen EADDRINUSE: address already in use 0.0.0.0:4723 如下图&#xff1a; 错误原因&#xff1a;Appium 默认的4723端口被占用 解决办法&#xff1a; 出现该提示&#xff0c;有可能是 Appium Server 已启动&#xff0c;关闭已经启动的 Appium Server 即可。472…

音视频类App广告变现如何破局,最大化广告变现收益,让应用增收?

音视频App已然成为了我们日常获取、发布和交换信息的重要方式&#xff0c;在音视频行业不断的拓展中&#xff0c;用户的渗透率提升。 据数据显示&#xff0c;我国网络视听用户的规模已达9亿人次&#xff0c;网民使用率也突破了90%。庞大的市场规模和用户需求吸引了大批开发者和…

SRE - 监控建设

监控⽂档 随着信息技术的迅速发展及其在商业和工业环境中的广泛应用,系统的可靠性成为了组织的生存之本。Site Reliability Engineering(SRE)作为一种实践的结合体,广泛地用于确保和提升软件系统的可靠性。其中,它的一个重要组成部分是制定和监控服务的关键性能指标(Ser…

行为型设计模式(五):访问者模式 观察者模式

访问者模式 Visitor 1、什么是访问者模式 访问者模式允许定义一些不改变数据结构的前提下的操作。通过这种方式&#xff0c;可以在不修改元素类的情况下定义新的操作。访问者模式常用于对复杂对象结构进行操作&#xff0c;而又不希望在这些对象上破坏封装性。 2、为什么使用…

摄影企业网站搭建的作用是什么

几乎每个成年人都有一部手机&#xff0c;在互联网信息时代&#xff0c;手机的作用不言而喻&#xff0c;拍照/摄像成为了不少人经常会做的事&#xff0c;拍一张美美的照片发到社交圈赢得赞声&#xff0c;或是为以后留下回忆或发给自己在意的人&#xff0c;但这只限于生活记叙类图…

收集足够苹果的最小花园周长(LeetCode日记)

LeetCode-1954-收集足够苹果的最小花园周长 题目信息: 给你一个用无限二维网格表示的花园&#xff0c;每一个 整数坐标处都有一棵苹果树。整数坐标 ( i , j ) (i, j) (i,j) 处的苹果树有 ∣ i ∣ ∣ j ∣ |i| |j| ∣i∣∣j∣ 个苹果。 你将会买下正中心坐标是 ( 0 , 0 )…

免费使用谷歌Gemini模型学习LLM编程

虽然谷歌的Gemini大语言模型爆出很大的乌龙&#xff0c;但这不影响我们使用Gemini Pro来学习LLM编程。 目前Bard还没有全部切换为Gemini Pro模型&#xff0c;但是作为程序员&#xff0c;已经不需要等待&#xff0c;可以直接调用Gemini Pro的接口了。谷歌这次开发者优先的做法值…

12.23C语言 指针

& 地址运算符&#xff0c;用于取地址 /*注释内容*/ //注释一行 *的意思&#xff1a;1.算术运算符 2.用于指针声明int *ptr;表示这个变量是一个指针3.数组元素访问&#xff1a;在数组名后面使用 * 可以表示数组的起始地址。例如&#xff1a; int arr[5] {1, 2, 3, 4, 5…