Java:内部类、枚举、泛型以及常用API --黑马笔记

内部类

内部类是类中的五大成分之一(成员变量、方法、构造器、内部类、代码块),如果一个类定义在另一个类的内部,这个类就是内部类。

当一个类的内部,包含一个完整的事物,且这个事物没有必要单独设计时,就可以把这个事物设计成内部类。

比如:汽车的内部有发动机,发动机是包含在汽车内部的一个完整事物,可以把发动机设计成内部类。

public class Car{//内部类public class Engine{}
}

内部类有四种形式,分别是成员内部类、静态内部类、局部内部类、匿名内部类 。

1.1 成员内部类

 成员内部类就是类中的一个普通成员,类似于成员变量、成员方法。

public class Outer {private int age = 99;public static String a="黑马";// 成员内部类public class Inner{private String name;private  int age = 88;//在内部类中既可以访问自己类的成员,也可以访问外部类的成员public void test(){System.out.println(age); //88System.out.println(a);   //黑马int age = 77;System.out.println(age); //77System.out.println(this.age); //88System.out.println(Outer.this.age); //99}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}}
}

成员内部类如何创建对象,格式如下:

//外部类.内部类 变量名 = new 外部类().new 内部类();
Outer.Inner in = new Outer().new Inner();
//调用内部类的方法
in.test();

内部类访问成员的特点:

1.既可以访问内部类成员、也可以访问外部类成员

2.如果内部类成员和外部类成员同名,可以使用  类名.this.成员   区分

1.2 静态内部类

静态内部类,其实就是在成员内部类的前面加了一个static关键字。静态内部类属于外部类自己持有。

public class Outer {private int age = 99;public static String schoolName="黑马";// 静态内部类public static class Inner{//静态内部类访问外部类的静态变量,是可以的;//静态内部类访问外部类的实例变量,是不行的public void test(){System.out.println(schoolName); //99//System.out.println(age);   //报错}}
}

静态内部类创建对象时,需要使用外部类的类名调用。

//格式:外部类.内部类 变量名 = new 外部类.内部类();
Outer.Inner in = new Outer.Inner();
in.test();

1.3 局部内部类

局部内部类是定义在方法中的类,和局部变量一样,只能在方法中有效。所以局部内部类的局限性很强,一般在开发中是不会使用的。

public class Outer{public void test(){//局部内部类class Inner{public void show(){System.out.println("Inner...show");}}//局部内部类只能在方法中创建对象,并使用Inner in = new Inner();in.show();}
}

1.4 匿名内部类

相比于前面几种内部类,匿名内部类就比较重要的。

我们还是先认识一下什么是匿名内部类?

匿名内部类是一种特殊的局部内部类;所谓匿名,指的是程序员不需要为这个类声明名字。

下面就是匿名内部类的格式:

new 父类/接口(参数值){@Override重写父类/接口的方法;
}

匿名内部类本质上是一个没有名字的子类对象、或者接口的实现类对象。

比如,先定义一个Animal抽象类,里面定义一个cry()方法,表示所有的动物有叫的行为,但是因为动物还不具体,cry()这个行为并不能具体化,所以写成抽象方法。

public abstract class Animal{public abstract void cry();
}

接下来,我想要在不定义子类的情况下创建Animal的子类对象,就可以使用匿名内部类

public class Test{public static void main(String[] args){//这里后面new 的部分,其实就是一个Animal的子类对象//这里隐含的有多态的特性: Animal a = Animal子类对象;Animal a = new Animal(){@Overridepublic void cry(){System.out.println("猫喵喵喵的叫~~~");}}a.eat(); //直线上面重写的cry()方法}
}

需要注意的是,匿名内部类在编写代码时没有名字,编译后系统会为自动为匿名内部类生产字节码,字节码的名称会以外部类$1.class的方法命名

匿名内部类的作用:简化了创建子类对象、实现类对象的书写格式。

我们再来看一下匿名内部类在实际中的应用场景。

只有在调用方法时,当方法的形参是一个接口或者抽象类,为了简化代码书写,而直接传递匿名内部类对象给方法。这样就可以少写一个类。比如,看下面代码:

public interface Swimming{public void swim();
}
public class Test{public static void main(String[] args){Swimming s1 = new Swimming(){public void swim(){System.out.println("狗刨飞快");}};go(s1);Swimming s1 = new Swimming(){public void swim(){System.out.println("猴子游泳也还行");}};go(s1);}//形参是Swimming接口,实参可以接收任意Swimming接口的实现类对象public static void go(Swimming s){System.out.println("开始~~~~~~~~");s.swim();System.out.println("结束~~~~~~~~");}
}

二、枚举

2.1 认识枚举

枚举是我们以后在项目开发中偶尔会用到的知识。

枚举是一种特殊的类,它的格式是:

public enum 枚举类名{枚举项1,枚举项2,枚举项3;
}

其实枚举项就表示枚举类的对象,只是这些对象在定义枚举类时就预先写好了,以后就只能用这几个固定的对象。

既然枚举是一个类的话,我们能不能在枚举类中定义构造器、成员变量、成员方法呢?答案是可以的。来看一下代码吧。

public enum A{//定义枚举项X,Y,Z("张三"); //枚举项后面加括号,就是在执行枚举类的带参数构造方法。//定义空构造器public A(){}//成员变量private String name;//定义带参数构造器public A(String name){this.name=name;}//成员方法public String getName(){return name;}...
}

虽然枚举类中可以像类一样,写一些类的其他成员,但是一般不会这么写,如果你真要这么干的话,到不如直接写普通类来的直接。

2.2 枚举的应用场景

枚举的应用场景是这样的:枚举一般表示一组信息,然后作为参数进行传输。

我们来看一个案例。比如我们现在有这么一个应用,用户进入应用时,需要让用户选择是女生、还是男生,然后系统会根据用户选择的是男生,还是女生推荐不同的信息给用户观看。

这里我们就可以先定义一个枚举类,用来表示男生、或者女生:

public class Constant{BOY,GRIL
}

再定义一个测试类,完成用户进入系统后的选择:

public class Test{public static void main(String[] args){//调用方法,传递男生provideInfo(Constant.BOY);}public static void provideInfo(Constant c){switch(c){case BOY:System.out.println("展示一些信息给男生看");break;case GRIL:System.out.println("展示一些信息给女生看");break;}}
}

最终再总结一下枚举的应用场景:枚举一般表示几个固定的值,然后作为参数进行传输

三、泛型

3.1 认识泛型

所谓泛型指的是,在定义类、接口、方法时,同时声明了一个或者多个类型变量(如:<E>),称为泛型类、泛型接口、泛型方法、它们统称为泛型。比如我们前面学过的ArrayList类就是一个泛型类。

ArrayList集合的设计者在定义ArrayList集合时,就已经明确ArrayList集合时给别人装数据用的,但是别人用ArrayList集合时候,装什么类型的数据他不知道,所以就用一个<E>表示元素的数据类型。 当别人使用ArrayList集合创建对象时,new ArrayList<String>就表示元素为String类型,new ArrayList<Integer>表示元素为Integer类型。

我们总结一下泛型的作用、本质:

1.泛型的好处:在编译阶段可以避免出现一些非法的数据。

2.泛型的本质:把具体的数据类型传递给类型变量。

3.2 自定义泛型类

泛型类,在实际工作中一般都是源代码中写好,我们直接用的,就是ArrayList<E>这样的,自己定义泛型类是非常少的。

自定义泛型类的格式如下:

//这里的<T,W>其实指的就是类型变量,可以是一个,也可以是多个。
public class 类名<T,W>{}

接下来,我们自己定义一个MyArrayList<E>泛型类,模拟一下自定义泛型类的使用。注意这里重点仅仅只是模拟泛型类的使用,所以方法中的一些逻辑是次要的,也不会写得太严谨。

//定义一个泛型类,用来表示一个容器
//容器中存储的数据,它的类型用<E>先代替用着,等调用者来确认<E>的具体类型。
public class MyArrayList<E>{private Object[] array = new Object[10];//定一个索引,方便对数组进行操作private int index;//添加元素public void add(E e){array[index]=e;index++;}//获取元素public E get(int index){return (E)array[index];}
}

接下来,我们写一个测试类,来测试自定义的泛型类MyArrayList是否能够正常使用

public class Test{public static void main(String[] args){//1.确定MyArrayList集合中,元素类型为String类型MyArrayList<String> list = new MyArrayList<>();//此时添加元素时,只能添加String类型list.add("张三");list.add("李四");//2.确定MyArrayList集合中,元素类型为Integer类型MyArrayList<Integer> list1 = new MyArrayList<>();//此时添加元素时,只能添加String类型list.add(100);list.add(200);}
}

3.3 自定义泛型接口

泛型接口其实指的是在接口中把不确定的数据类型用<类型变量>表示。定义格式如下:

//这里的类型变量,一般是一个字母,比如<E>
public interface 接口名<类型变量>{}

比如,我们现在要做一个系统要处理学生和老师的数据,需要提供2个功能,保存对象数据、根据名称查询数据,要求:这两个功能处理的数据既能是老师对象,也能是学生对象。

首先我们得有一个学生类和老师类:

public class Teacher{}
public class Student{}

我们定义一个Data<T>泛型接口,T表示接口中要处理数据的类型。

public interface Data<T>{public void add(T t);public ArrayList<T> getByName(String name);
}

接下来,我们写一个处理Teacher对象的接口实现类:

//此时确定Data<E>中的E为Teacher类型,
//接口中add和getByName方法上的T也都会变成Teacher类型
public class TeacherData implements Data<Teacher>{public void add(Teacher t){}public ArrayList<Teacher> getByName(String name){}
}

接下来,我们写一个处理Student对象的接口实现类:

//此时确定Data<E>中的E为Student类型,
//接口中add和getByName方法上的T也都会变成Student类型
public class StudentData implements Data<Student>{public void add(Student t){}public ArrayList<Student> getByName(String name){}
}

在实际工作中,一般也都是框架底层源代码把泛型接口写好,我们实现泛型接口就可以了。

3.4 泛型方法

泛型方法的格式:

public <泛型变量,泛型变量> 返回值类型 方法名(形参列表){}

接下我们看一个泛型方法的案例:

public class Test{public static void main(String[] args){//调用test方法,传递字符串数据,那么test方法的泛型就是String类型String rs = test("test");//调用test方法,传递Dog对象,那么test方法的泛型就是Dog类型Dog d = test(new Dog()); }//这是一个泛型方法<T>表示一个不确定的数据类型,由调用者确定public static <T> test(T t){return t;}
}

3.5 泛型限定

泛型限定的意思是对泛型的数据类型进行范围的限制。有如下的三种格式:

1.<?> 表示任意类型

2.<? extends 数据类型> 表示指定类型或者指定类型的子类

3.<? super 数据类型> 表示指定类型或者指定类型的父类

下面我们演示一下,假设有Car作为父类,BENZ,BWM两个类作为Car的子类,代码如下:

class Car{}
class BENZ extends Car{}
class BWN extends Car{}public class Test{public static void main(String[] args){//1.集合中的元素不管是什么类型,test1方法都能接收ArrayList<BWM> list1 = new ArrayList<>();ArrayList<Benz> list2 = new ArrayList<>();ArrayList<String> list3 = new ArrayList<>();test1(list1);test1(list2);test1(list3);//2.集合中的元素只能是Car或者Car的子类类型,才能被test2方法接收ArrayList<Car> list4 = new ArrayList<>();ArrayList<BWM> list5 = new ArrayList<>();test2(list4);test2(list5);//2.集合中的元素只能是Car或者Car的父类类型,才能被test3方法接收ArrayList<Car> list6 = new ArrayList<>();ArrayList<Object> list7 = new ArrayList<>();test3(list6);test3(list7);}public static void test1(ArrayList<?> list){}public static void test2(ArrayList<? extends Car> list){}public static void test3(ArrayList<? super Car> list){}
}

3.6 泛型擦除

什么是泛型擦除呢?也就是说泛型只能编译阶段有效,一旦编译成字节码,字节码中是不包含泛型的。而且泛型只支持引用数据类型,不支持基本数据类型。

四、常用API

API(Application Programming interface)意思是应用程序编程接口,说人话就是Java帮我们写好的一些程序,如:类、方法等,我们直接拿过来用就可以解决一些问题。

4.1 Object类

我们先来学习toString()方法。

public String toString()调用toString()方法可以返回对象的字符串表示形式。默认的格式是:“包名.类名@哈希值16进制”

假设有一个学生类如下:

public class Student{private String name;private int age;public Student(String name, int age){this.name=name;this.age=age;}
}

再定义一个测试类:

public class Test{public static void main(String[] args){Student s1 = new Student("赵敏",23);System.out.println(s1.toString()); }
}

打印结果如下:

如果,在Student类重写toString()方法,那么我们可以返回对象的属性值,代码如下:

public class Student{private String name;private int age;public Student(String name, int age){this.name=name;this.age=age;}@Overridepublic String toString(){return "Student{name=‘"+name+"’, age="+age+"}";}
}

运行测试类,结果如下:

接下来,我们学习一下Object类的equals方法:

public boolean equals(Object o)判断此对象与参数对象是否"相等"

我们写一个测试类,测试一下:

public class Test{public static void main(String[] args){Student s1 = new Student("赵薇",23);Student s2 = new Student("赵薇",23);//equals本身也是比较对象的地址,和"=="没有区别System.out.println(s1.equals(s2)); //false//"=="比较对象的地址System.out.println(s1==s2); //false}
}

但是如果我们在Student类中,把equals方法重写了,就按照对象的属性值进行比较:

public class Student{private String name;private int age;public Student(String name, int age){this.name=name;this.age=age;}@Overridepublic String toString(){return "Student{name=‘"+name+"’, age="+age+"}";}//重写equals方法,按照对象的属性值进行比较@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Student student = (Student) o;if (age != student.age) return false;return name != null ? name.equals(student.name) : student.name == null;}
}

再运行测试类,效果如下:

接下来,我们学习Object类的clone()方法,克隆。意思就是某一个对象调用这个方法,这个方法会复制一个一模一样的新对象,并返回。

clone方法是Object类中的一个被protected和native修饰的方法,被native就代表它的实现源码是用c++实现的,只不过是我们无法去修改它的代码罢了。

public Object clone()克隆当前对象,返回一个新对象

想要调用clone()方法,必须让被克隆的类实现Cloneable接口。如我们准备克隆User类的对象,代码如下:

public class User implements Cloneable{private String id; //编号private String username; //用户名private String password; //密码private double[] scores; //分数public User() {}public User(String id, String username, String password, double[] scores) {this.id = id;this.username = username;this.password = password;this.scores = scores;}//...get和set...方法自己加上@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}

接着,我们写一个测试类,克隆User类的对象。

public class Test {public static void main(String[] args) throws CloneNotSupportedException {User u1 = new User(1,"zhangsan","wo666",new double[]{99.0,99.5});//调用方法克隆得到一个新对象User u2 = (User) u1.clone();System.out.println(u2.getId());System.out.println(u2.getUsername());System.out.println(u2.getPassword());System.out.println(u2.getScores()); }
}

我们发现,克隆得到的对象u2它的属性值和原来u1对象的属性值是一样的。

上面演示的克隆方式,是一种浅克隆的方法,浅克隆的意思:拷贝出来的对象封装的数据与原对象封装的数据一模一样(引用类型拷贝的是地址值)。如下图所示:

还有一种拷贝方式,称之为深拷贝,拷贝原理如下图所示:

下面演示一下深拷贝User对象:

public class User implements Cloneable{private String id; //编号private String username; //用户名private String password; //密码private double[] scores; //分数public User() {}public User(String id, String username, String password, double[] scores) {this.id = id;this.username = username;this.password = password;this.scores = scores;}//...get和set...方法自己加上@Overrideprotected Object clone() throws CloneNotSupportedException {//先克隆得到一个新对象User u = (User) super.clone();//再将新对象中的引用类型数据,再次克隆u.scores = u.scores.clone();return u;}
}

4.2 Objects类

Objects是一个工具类,提供了一些方法可以对任意对象进行操作。主要方法如下:

下面写代码演示一下这几个方法:

public class Test{public static void main(String[] args){String s1 = null;String s2 = "itheima";//这里会出现NullPointerException异常,调用者不能为nullSystem.out.println(s1.equals(s2));//此时不会有NullPointerException异常,底层会自动先判断空System.out.println(Objects.equals(s1,s2));//判断对象是否为null,等价于==System.out.println(Objects.isNull(s1)); //trueSystem.out.println(s1==null); //true//判断对象是否不为null,等价于!=System.out.println(Objects.nonNull(s2)); //trueSystem.out.println(s2!=null); //true}
}

4.3 基本类型包装类

为什么要学习包装类呢?因为在Java中有一句很经典的话,万物皆对象。Java中的8种基本数据类型还不是对象,所以要把它们变成对象,变成对象之后,可以提供一些方法对数据进行操作。

Java中8种基本数据类型都用一个包装类与之对一个,如下图所示:

我们学习包装类,主要学习两点:

1.创建包装类的对象方式、自动装箱和拆箱的特性;

2. 利用包装类提供的方法对字符串和基本类型数据进行相互转换

我们先来学习,创建包装类对象的方法,以及包装类的一个特性叫自动装箱和自动拆箱。我们以Integer为例,其他的可以自己学,都是类似的。

//1.创建Integer对象,封装基本类型数据10
Integer a = new Integer(10);//2.使用Integer类的静态方法valueOf(数据)
Integer b = Integer.valueOf(10);//3.还有一种自动装箱的写法(意思就是自动将基本类型转换为引用类型)
Integer c = 10;//4.有装箱肯定还有拆箱(意思就是自动将引用类型转换为基本类型)
int d = c;//5.装箱和拆箱在使用集合时就有体现
ArrayList<Integer> list = new ArrayList<>();
//添加的元素是基本类型,实际上会自动装箱为Integer类型
list.add(100);
//获取元素时,会将Integer类型自动拆箱为int类型
int e = list.get(0);

在开发中,经常使用包装类对字符串和基本类型数据进行相互转换。

1.把字符串转换为数值型数据:包装类.parseXxx(字符串)

public static int parseInt(String s)把字符串转换为基本数据类型

2.将数值型数据转换为字符串:包装类.valueOf(数据):

public static String valueOf(int a)把基本类型数据转换为

写一个测试类演示一下:

//1.字符串转换为数值型数据
String ageStr = "29";
int age1 = Integer.parseInt(ageStr);String scoreStr = 3.14;
double score = Double.prarseDouble(scoreStr);//2.整数转换为字符串,以下几种方式都可以(挑中你喜欢的记一下)
Integer a = 23;
String s1 = Integer.toString(a);
String s2 = a.toString();
String s3 = a+"";
String s4 = String.valueOf(a);

 

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

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

相关文章

git flow与分支管理

git flow与分支管理 一、git flow是什么二、分支管理1、主分支Master2、开发分支Develop3、临时性分支功能分支预发布分支修补bug分支 三、分支管理最佳实践1、分支名义规划2、环境与分支3、分支图 四、git flow缺点 一、git flow是什么 Git 作为一个源码管理系统&#xff0c;…

JavaScript鼠标移动事件

&#x1f9d1;‍&#x1f393; 个人主页&#xff1a;《爱蹦跶的大A阿》 &#x1f525;当前正在更新专栏&#xff1a;《VUE》 、《JavaScript保姆级教程》、《krpano》、《krpano中文文档》 ​ ​ ✨ 前言 鼠标移动是用户界面中非常重要的交互行为。学习区分不同的鼠标移动事…

PySpark(三)RDD持久化、共享变量、Spark内核制度,Spark Shuffle、Spark执行流程

目录 RDD持久化 RDD 的数据是过程数据 RDD 缓存 RDD CheckPoint 共享变量 广播变量 累加器 Spark 内核调度 DAG DAG 的宽窄依赖和阶段划分 内存迭代计算 Spark是怎么做内存计算的? DAG的作用?Stage阶段划分的作用? Spark为什么比MapReduce快&#xff1f; Spa…

机器学习10-特征缩放

特征缩放的目的是确保不同特征的数值范围相近&#xff0c;使得模型在训练过程中更加稳定&#xff0c;加速模型收敛&#xff0c;提高模型性能。具体而言&#xff0c;零均值和单位方差的目标有以下几点好处&#xff1a; 1. 均值为零&#xff08;Zero Mean&#xff09;&#xff1a…

红队打靶练习:GLASGOW SMILE: 1.1

目录 信息收集 1、arp 2、nmap 3、nikto 4、whatweb 目录探测 1、gobuster 2、dirsearch WEB web信息收集 /how_to.txt /joomla CMS利用 1、爆破后台 2、登录 3、反弹shell 提权 系统信息收集 rob用户登录 abner用户 penguin用户 get root flag 信息收集…

【Python】使用 requirements.txt 与 pytorch 相关配置

【Python】使用 requirements.txt 与 pytorch 相关配置 前言一、pip1、导出结果含有路径2、导出不带路径的 二、Conda1、导出requirements.txt2、导出yml 文件 三、第三方包&#xff1a;pipreqs&#xff08;推荐&#xff09;1、创建并激活conda环境2、安装requirements文件的pi…

Linux进程间通信(2)--System V共享内存 | 消息队列 | 信号量

目录 实现原理 使用系统调用创建共享内存 使用shmget函数创建共享内存&#xff1a; 使用shmat函数将共享内挂接到进程地址空间的共享区 使用shmdt函数取消共享内存与进程地址空间的关联 ​编辑 使用shmctl函数释放共享内存 共享内存的属性 System V消息队列 &#xff…

文件上传-Webshell

Webshell简介 webshell就是以aspphpjsp或者cgi等网页文件形式存在的一种命令执行环境&#xff0c;也可以将其称做为一种网页木马后门。 攻击者可通过这种网页后门获得网站服务器操作权限&#xff0c;控制网站服务器以进行上传下载文件、查看数据库、执行命令等… 什么是木马 …

docker 基于容器创建本地web容器化镜像

一、docker 基于容器创建本地web容器化镜像 1、启动指定buysbox 镜像 docker run --name b1 -it busybox:latest 2、创建目录&#xff0c;并创建html mkdir -p /data/html vi index.html 内容自定义例如&#xff1a;<h1>welcome to busybox<h1> 3、新增窗口&am…

类和对象 第六部分第二小节:继承方式

前情提要&#xff1a;继承的语法&#xff1a;class 子类 继承方式&#xff1a;父类 继承方式一共有3种&#xff1a; 代码案例&#xff1a; 前置代码 #include<iostream> using namespace std; class Base1 { public:int m_A; protected:int m_B; private:int m_C; };公共…

linux C编程入门

Ubuntu 下也有一些可以进行编程的工具&#xff0c;但是大多都只是编辑器&#xff0c; 也就是只能进行代码编辑&#xff0c;如果要编译的话就需要用到 GCC 编译器&#xff0c;使用 GCC 编译器肯定就 要接触到Makefile。 1&#xff1a;hello world!!! 我们所说的编写代码包括两部…

Qt网络编程-TCP与UDP

网络基础 TCP与UDP基础 关于TCP与UDP的基础这里就不过多介绍了&#xff0c;具体可以查看对应百度百科介绍&#xff1a; TCP&#xff08;传输控制协议&#xff09;_百度百科 (baidu.com) UDP_百度百科 (baidu.com) 需要知道这两者的区别&#xff1a; 可靠性&#xff1a; TC…

day35 数组map和join方法(字符串拼接)

目录 map方法join方法 map方法 使用场景&#xff1a;map 可以遍历数组处理数据&#xff0c;并且返回新的数组map 也称为映射。映射是个术语&#xff0c;指两个元素的集之间元素相互“对应”的关系。map重点在于有返回值&#xff0c;forEach没有返回值&#xff08;undefined&am…

使用 Docker 镜像预热提升容器启动效率详解

概要 在容器化部署中,Docker 镜像的加载速度直接影响到服务的启动时间和扩展效率。本文将深入探讨 Docker 镜像预热的概念、必要性以及实现方法。通过详细的操作示例和实践建议,读者将了解如何有效地实现镜像预热,以加快容器启动速度,提高服务的响应能力。 Docker 镜像预热…

蓝桥杯(Web大学组)2022国赛真题:水果消消乐

思路&#xff1a; 记录点击次数&#xff0c;点击次数为1时&#xff0c;记录点击下标&#xff08;用于隐藏or消除&#xff09;、点击种类&#xff0c;点击次数为2时&#xff0c;判断该下标所对应种类与第一次是否相同 相同&#xff1a;两个都visibility:hidden &#xff08;占…

阿里云资源包管理

-我守在梦的出口&#xff0c;任凭人来人走 阿里云对象存储中的下行流量包是什么&#xff1f; 阿里云对象存储&#xff08;OSS&#xff09;中的下行流量包是一种预付费的流量套餐&#xff0c;用于支付从阿里云 OSS 存储桶下载数据产生的流量费用。当你的应用程序或用户从 OSS 存…

JS中常用占位符使用方法详解_ |%s|%d|%f|%o|%O|%c|

在 JavaScript 中&#xff0c;%s 是一种字符串格式化占位符&#xff0c;用于将字符串插入到另一个字符串中的指定位置。这种方法基于 C 语言的 printf() 函数&#xff0c;但在 JavaScript 中有一些变化。 在 JavaScript 中&#xff0c;%s 可以接受任何类型的值&#xff0c;并将…

复制和粘贴文本时剥离格式的5种方法(MacWindows)

您可能每天复制和粘贴多次。虽然它是一个非常方便的功能&#xff0c;但最大的烦恼之一就是带来了特殊的格式。从网络上获取一些文本&#xff0c;您经常会发现粘贴到文档中时&#xff0c;它保持原始样式。 我们将展示如何使用一些简单的技巧在不格式化的情况下复制和粘贴。 1.…

95.网游逆向分析与插件开发-游戏窗口化助手-窗口化助手显示与大小调整

内容参考于&#xff1a;易道云信息技术研究院VIP课 上一个内容&#xff1a;地图数据获取的逆向分析与C代码还原 码云地址&#xff08;游戏窗口化助手 分支&#xff09;&#xff1a;https://gitee.com/dye_your_fingers/sro_-ex.git 码云版本号&#xff1a;e85c0fc8b85895c8c…

ZigBee学习——在官方例程上实现串口通信

Z-Stack版本为3.0.2 IAR版本为10.10.1 文章目录 一、添加头文件二、定义接收缓冲区三、编写Uart初始化函数四、编写串口回调函数五、函数声明六、函数调用七、可能遇到的问题(function “halUartInit“ has no prototype) 以下所有操作都是在APP层进行&#xff0c;也就是这个文…