Day11-内部类代码块枚举

news2024/11/18 2:43:57

文章目录

  • Day11-内部类&代码块&枚举
    • 学习目标
    • 1. 内部类
      • 1.1 成员内部类
      • 1.2 局部内部类
      • 1.3 匿名内部类
      • 1.4 静态内部类
    • 2. 代码块
      • 2.1 静态代码块
      • 2.2 类的初始化
      • 2.3 构造代码块
      • 2.4 实例对象的初始化
      • 2.5 代码块的执行顺序
    • 3. 单例设计模式
      • 3.1 饿汉式
      • 3.2 懒汉式
    • 4. 枚举类
      • 4.1 Enum的使用
      • 4.2 常见方法

Day11-内部类&代码块&枚举

学习目标

  • 能够定义使用内部类
  • 能够说出四种不同内部类的特点
  • 能够定义并使用静态代码块
  • 能够说出类和实例对象的初始化过程
  • 能够说出代码块的调用顺序
  • 能够定义枚举并说出枚举常见方法的用法

1. 内部类

在一个类A里,我们可以定义变量,也可以定义方法。思考一下,在A类里还能在定义一个B类吗?这种语法在Java里是允许的,这种情况下,B类可以被称为内部类,A类被称为外部类。

当一个类的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整的结构又只为外部事物提供服务,不在其他地方单独使用,那么整个内部的完整结构最好使用内部类。

根据内部类定义的方式不同,可以讲内部类分为四种:

  • 成员内部类
  • 局部内部类
  • 静态内部类
  • 匿名内部类

注意:对于普通的类来说,我们只能使用缺省或者public权限修饰符;而对于有些内部类,可以使用全部的四种权限修饰符。

1.1 成员内部类

语法格式:

[修饰符] class 外部类{
    [修饰符] class 内部类{  
    }
}

示例:

public class Test {
    public static void main(String[] args) {
        // 直接使用 new Outer().new Inner() 方法创建一个Inner对象
        Outer.Inner inner1 = new Outer().new Inner();  
        
        // 创建一个 Outer 对象,再调用 Outer 对象的 getInner方法,在getInner方法里创建并返回 Inner 对象
        Outer.Inner inner2 = new Outer().getInner();
    }
}
class Outer {
    int age = 19;
    private String name = "jack";
	
    private void test() {
        System.out.println("我是Outer类里的test方法");
    }
    
    class Inner {  // 可以把 Inner 想象成为和 age / name一样,只不过它的数据类型是class
        // static int a = 10;  报错,不能使用 static
        static final int b = 1;  // 可以使用 static final 定义常量
        private void test() {
            System.out.println("我是Inner类里的test方法");
        }
        public void demo() {
            // 内部类可以直接访问外部类的成员,包括私有成员。
            System.out.println(name);
            this.test();  // 等价于 test() 调用的是内部类的test方法
            Outer.this.test(); // 需要使用 Outer.this 调用外部类的 test 方法
        }
    }
    public static void foo() {
        // Inner inner = new Inner();  报错!外部static成员不允许访问非静态内部类
    }
    public Inner getInner() {
        return new Inner();
    }
}

成员内部类特点:

  1. 不能使用 static关键字,但是可以使用static final关键字定义常量。
  2. 内部类可以直接访问外部类的成员(包括私有成员)。
  3. 内部类如果想要调用外部类的方法,需要使用外部类名.this.外部方法名
  4. 可以使用final修饰内部类,表示不能被继承。
  5. 编译以后也会有自己独立的字节码文件,只不过文件名是Outer$Inner.class
  6. 外部函数的static成员里,不允许访问成员内部类。
  7. 可以在外部类里创建内部类对象然后再通过方法返回,同时,也可以使用new Outer().new Inner()在外部直接访问内部类。

1.2 局部内部类

局部内部类的使用和成员内部类的使用基本一致,只是局部内部类定义在外部类的方法中,就像局部变量一样,并不是外部类的成员。局部内部类在方法外是无法访问到的,但它的实例可以从方法中返回,并且实例在不再被引用之前会一直存在。

语法格式:

[修饰符] class 外部类{
    [修饰符] 返回值类型  方法名([形参列表]){
            [final/abstract] class 内部类{
    	}
    }    
}

示例:

class Outer {
    int age = 19;
	static int m = 10;
    
    public void test() {
        // final String y = "good";
        String y = "good";  // JDK8 以后,final可以省略
        class Inner {  // 定义在外部类的某个方法里
            // static int a = 10; 不能定义静态变量!  
            private  void demo() {
                System.out.println(age);
                // 不能修改外部函数的局部变量
				// y = 'yes';
                // 只能访问被 final 修饰的外部函数的局部变量
                // JDK8 以后,如果外部函数的局部变量没有加 final,编译器会自动加 final
                System.out.println(y);
            }
        }
        Inner inner = new Inner();
        inner.demo();
    }
}

局部内部类特点:

  1. 定义在类的某个方法里,而不是直接定义在类里。
  2. 局部内部类前面不能有权限修饰符!
  3. 局部内部类里不能使用static声明变量!
  4. 局部内部类中能访问外部类的静态成员。
  5. 如果这个局部内部类所在的方法是静态方法,它无法访问访问外部类的非静态成员。
  6. 局部内部类可以访问外部函数的局部变量,但是这个局部变量必须要被final修饰。JDK8以后,如果局部变量被局部内部类使用了,会自动在前面加final.

思考: 为什么局部变量前要加final.

public class TestInner{
	public static void main(String[] args) {
		A obj = Outer.method();
		//因为如果c不是final的,那么method方法执行完,method的栈空间就释放了,那么c也就消失了
		obj.a();//这里打印c就没有中可取了,所以把c声明为常量,存储在方法区中
	}
}

interface A{
	void a();
}
class Outer{
	public static A method(){
		final int c = 3;
		class Sub implements A{
			@Override
			public void a() {
				System.out.println("method.c = " + c);
			}
		}
		return new Sub();
	}
}

1.3 匿名内部类

语法格式:

new 父类名或者接口名(){
    // 方法重写
    @Override 
    public void method() {
        // 执行语句
    }
};

实例:

abstract class Animal {
    abstract void shout();
}
class Demo {
    public void demo() {
        Animal animal = new Animal(){
            @Override
            void shout() {
                System.out.println("动物正在叫");
            }
        };
    }
}

匿名内部类的特点:

  1. 匿名内部类就是一种特殊的局部内部类,只不过没有名称而已,它的基本特点和局部内部类一致。
  2. 匿名内部类不能有构造器,匿名内部类没有类名,肯定无法声明构造器。
  3. 匿名内部类的前提是,这个内部类必须要继承自一个父类或者父接口!
  4. 匿名内部类是接口的一种常见简化写法,也是我们开发中最常使用的一种内部类。它的本质是一个实现了父类或者父接口具体方法的一个匿名对象。

1.4 静态内部类

静态内部类也被称为嵌套类,不同于前三种内部类,静态内部类不会持有外部类对象的引用。

语法格式:

[修饰符] class 外部类{    
    [其他修饰符] static class 内部类{    }
}

示例:

class Outer {
    int age = 19;
    static String type = "outer";

    static class Inner {  // 需要使用 static 关键字
        static int x = 1;  // 能够定义静态变量
        public static void test() {
            // 只能访问外部的静态变量,不能访问非静态变量
            // System.out.println(age);
            System.out.println(type);
        }
    }
    public void  demo() {
        System.out.println(Inner.x);  // 外部类可以直接通过 内部类.静态变量名,不需要创建对象
    }
}

静态内部类特点:

  1. 使用static关键字修饰。
  2. 在静态内部类里,可以使用static关键字定义静态成员。
  3. 只能访问外部的静态成员,不能访问外部的非静态成员。
  4. 外部类可以直接通过静态内部类名.静态成员名访问静态内部类的静态成员。

其实严格的讲(在James Gosling等人编著的《The Java Language Specification》)静态内部类不是内部类,而是类似于C++的嵌套类的概念,外部类仅仅是静态内部类的一种命名空间的限定名形式而已。所以接口中的内部类通常都不叫内部类,因为接口中的内部成员都是隐式是静态的。例如:Map.Entry。

2. 代码块

Java中包括四种代码块:

  1. 普通代码块:就是类里方法体代码。
  2. 构造代码块:类里直接使用 {} 编写的代码。
  3. 静态代码块:在构造代码块前添加static关键字。
  4. 同步代码块:使用synchronize关键字包裹起来的代码块,用于多线程。

普通代码块就是方法体的代码,这里就不再赘述。下面我们来看一下构造代码块和静态代码块。

2.1 静态代码块

语法结构:

[修饰符] class 类名{
    static{
        静态代码块语句;
    }
}

示例:

public class Demo {
    public static void main(String[] args) {
        System.out.println("我是Main方法");
        Demo d = new Demo();
    }
    Demo() {
        System.out.println("我是构造方法");
    }
    
    private static int a;
    static {
        a = 10;  // 静态代码块可以用于对静态变量初始化
        System.out.println("我是静态代码块");
    }
}

特点:

  1. 使用static关键字修饰,写在类里,方法外,用来对类进行初始化。
  2. 一个类里可以有多个静态代码块,但是通常情况下只会定义一个。
  3. 随着类加载而执行,只执行一次,只要类加载就会执行,所以执行的优先级很高。
  4. 一般情况下,如果有些代码必须在项目启动的时候就执行的时候,就需要使用静态代码块。

2.2 类的初始化

类被加载内存后,会在方法区创建一个Class对象(后面反射章节详细学习)来存储该类的所有信息。此时会为类的静态变量分配内存,然后为类变量进行初始化。在加载类的过程中,JVM会调用<clinit>方法,专门来对类变量或者静态代码块进行初始化。

public class Test{
    public static void main(String[] args){
    	Father.test();
    }
}
class Father{
	private static int a = getNumber();
	static{
		System.out.println("Father(1)");
	}
	private static int b = getNumber();
	static{
		System.out.println("Father(2)");
	}
	
	public static int getNumber(){
		System.out.println("getNumber()");
		return 1;
	}
	
	public static void test(){
		System.out.println("Father:test()");
	}
}

运行结果:
getNumber()
Father(1)
getNumber()
Father(2)
Father:test()

在这里插入图片描述

public class Test{
    public static void main(String[] args){
    	Son.test();
        System.out.println("-----------------------------");
        Son.test();
    }
}
class Father{
	private static int a = getNumber();
	static{
		System.out.println("Father(1)");
	}
	private static int b = getNumber();
	static{
		System.out.println("Father(2)");
	}
	
	public static int getNumber(){
		System.out.println("Father:getNumber()");
		return 1;
	}
}
class Son extends Father{
	private static int a = getNumber();
	static{
		System.out.println("Son(1)");
	}
	private static int b = getNumber();
	static{
		System.out.println("Son(2)");
	}
	
	public static int getNumber(){
		System.out.println("Son:getNumber()");
		return 1;
	}
	
	public static void test(){
		System.out.println("Son:test()");
	}	
}
// 运行结果
Father:getNumber()
Father(1)
Father:getNumber()
Father(2)
Son:getNumber()
Son(1)
Son:getNumber()
Son(2)
Son:test()
-----------------------------
Son:test()

2.3 构造代码块

语法结构:

{
    //代码块里的内容
}

示例:

package com.atguigu.java;

public class Demo {
    public static void main(String[] args) {
        System.out.println("我是main方法");

        Demo d1 = new Demo();
        System.out.println(d1.getName());

        Demo d2 = new Demo();

    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    private String name;

    public Demo() {
        System.out.println("我是构造方法");
    }
    {
        System.out.println("我是构造代码块");
        this.name = "jack";
    }
}
// 我是main方法
// 我是构造代码块
// 我是构造方法
// jack
// 我是构造代码块
// 我是构造方法

特点:

  1. 对象一建立就会执行构造代码块,构造代码块先于构造方法执行,用来给对象进行初始化。
  2. 每创建一个对象都会调用一次构造代码块。
  3. 构造代码块是给所有对象统一初始化,构造函数是给各自对应的对象初始化。
  4. 如果每个实例对象都需要统一的初始化,可以考虑将这部分代码写入到构造代码块里。

2.4 实例对象的初始化

除了<clinit>方法初始化类以外,在创建实例对象时,还会自动调用<init>方法对实例对象进行初始化。

使用一个类来实例化对象的几种方式:

  1. 最常见的方式,使用关键字new来创建一个实例对象。
  2. 使用反射,调用Class或者java.lang.reflect.Constructor对象的newInstance()方法。
  3. 调用对象的clone()方法。
  4. 调用java.io.ObjectInputStream类的getOjbect()方法序列化。
public class Test{
    public static void main(String[] args){
    	Father f1 = new Father();
    	Father f2 = new Father();
    }
}
class Father{
	private int a = getNumber();
	private String info;
	{
		System.out.println("Father(1)");
	}
	Father(){
		System.out.println("Father()无参构造");
	}
	Father(String info){
		this.info = info;
		System.out.println("Father(info)有参构造");
	}
	private int b = getNumber();
	{
		System.out.println("Father(2)");
	}
	
	public int getNumber(){
		System.out.println("Father:getNumber()");
		return 1;
	}
}
运行结果:
Father:getNumber()
Father(1)
Father:getNumber()
Father(2)
Father()无参构造
Father:getNumber()
Father(1)
Father:getNumber()
Father(2)
Father(info)有参构造

在这里插入图片描述

2.5 代码块的执行顺序

先初始化类,加载类变量(static类型变量和static代码块),再调用构造代码块,然后再调用构造方法。

class Father {
    Father() {
        System.out.println("我是Father里的构造方法");
    }
    static {
        System.out.println("我是Father里的静态代码块");
    }
    {
        System.out.println("我是Father里的构造代码块");
    }
}

public class Demo extends Father {
    public static void main(String[] args) {
        System.out.println("我是Main方法");
        Demo d = new Demo();
    }
    Demo() {
        System.out.println("我是Demo构造方法");
    }
    static {
        System.out.println("我是Demo静态代码块");
    }
    {
        System.out.println("我是Demo构造代码块");
    }
}

// 我是Father里的静态代码块
// 我是Demo静态代码块
// 我是Main方法
// 我是Father里的构造代码块
// 我是Father里的构造方法
// 我是Demo构造代码块
// 我是Demo构造方法

3. 单例设计模式

单例模式,是一种常用的软件设计模式,在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中应用该模式的类一个类只有一个实例,即一个类只有一个对象实例。例如,windows操作系统里的回收站。

步骤:

  1. 将构造方法私有化,使其不能在类的外部通过new关键字实例化该类对象。
  2. 在该类内部产生一个唯一的实例化对象,并且将其封装为private static final类型。
  3. 定义一个静态方法返回这个唯一对象。

单例设计模式分为饿汉式(立即加载型)和懒汉式(延迟加载型)。由于懒汉式有线程安全问题,又衍生出了线程安全版的懒汉式以及DLC双检查锁(最佳实现方式)的懒汉式。

3.1 饿汉式

立即加载就是使用类的时候已经将对象创建完毕(不管以后会不会使用到该实例化对象,先创建了再说。很着急的样子,故又被称为“饿汉模式”),常见的实现办法就是直接new实例化。

public class Singleton {

    // 将自身实例化对象设置为一个属性,并用static修饰
    private static final Singleton instance = new Singleton();
    
    // 构造方法私有化
    private Singleton() {}
    
    // 静态方法返回该实例
    public static Singleton getInstance() {
        return instance;
    }
}
  • 优点:实现起来简单,没有多线程同步问题。
  • 缺点:当类SingletonTest被加载的时候,会初始化static的instance,静态变量被创建并分配内存空间,从这以后,这个static的instance对象便一直占着这段内存(即便你还没有用到这个实例),当类被卸载时,静态变量被摧毁,并释放所占有的内存,因此在某些特定条件下会耗费内存。

3.2 懒汉式

延迟加载就是调用get()方法时实例才被创建(先不急着实例化出对象,等要用的时候才给你创建出来。不着急,故又称为“懒汉模式”),常见的实现方法就是在get方法中进行new实例化。

public class Singleton {

    // 将自身实例化对象设置为一个属性,并用static修饰
    private static Singleton instance;
    
    // 构造方法私有化
    private Singleton() {}
    
    // 静态方法返回该实例
    public static Singleton getInstance() {
        if(instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}
  • 优点:实现起来比较简单,当类SingletonTest被加载的时候,静态变量static的instance未被创建并分配内存空间,当getInstance方法第一次被调用时,初始化instance变量,并分配内存,因此在某些特定条件下会节约了内存。
  • 缺点:在多线程环境中,这种实现方法是完全错误的,根本不能保证单例的状态。

4. 枚举类

有些时候,如果一个类的对象是有限并且固定的,可以考虑使用枚举类。在JDK1.5之前,需要自己手动的实现。

public class Test {
    public static void main(String[] args) {
        System.out.println(Season.SPRING);
    }
}

class Season {
    private Season() {
    }
    public static final Season SPRING = new Season();
    public static final Season SUMMER = new Season();
    public static final Season AUTUMN = new Season();
    public static final Season WINTER = new Season();
}

4.1 Enum的使用

枚举(enum)类型是Java 5新增的特性,它是一种新的类型,允许用常量来表示特定的数据。有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法。

语法格式:

enum 枚举类类名 {
    对象1,对象2,对象3;
}

示例:

public enum Season{
    // SPRING(),SUMMER(),AUTUMN(),WINTER();  调用构造函数,创建了四个对象,小括号可以省略
    
    SPRINT,SUMMER,AUTUMN,WINTER;  // 创建了四个对象
    // private Season(){} 构造方法可以不写,默认就有一个空参数构造方法
}

public enum WeekDay {
    // 创建的实例对象时,必须要调用构造方法传入 name 参数
    MON("周一"), TUE("周二"), WED("周三"), THU("周四"), FRI("周五"), SAT("周六"), SUN("周日");
    
    private String name;
    WeekDay(String name) {  // 还能自定义构造方法
        this.name = name;
    }
    
    // 像正常的类一样,可以使用 getter/setter 方法
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

枚举特点:

  1. 所有的枚举都继承自java.lang.Enum类,由于Java 不支持多继承,所以枚举对象不能再继承其他类(但是可以实现接口)。
  2. 枚举类的所有实例对象都必须放在第一行展示,并且默认都是以public static final修饰的常量,所以变量名通常都全大写。
  3. 在创建实例对象时,不需使用new 关键字,也不需使用小括号显式调用构造器
  4. 使用enum定义、非抽象的枚举类默认使用final修饰,不可以被继承。
  5. 枚举类的构造器只能是私有的,不允许在外部创建对象。

4.2 常见方法

方法名作用
toString返回的是常量名(对象名),可以重写
name返回的是常量名(对象名),不推荐使用,建议使用toString
values返回该枚举类的所有的常量对象,返回类型是当前枚举的数组类型。
valueOf根据常量名,返回一个枚举对象。
ordinal返回枚举常量的序数(它在枚举声明中的位置,其中初始常量序数为零)。

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

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

相关文章

Sora--首个大型视频生成模型

Sora--首个大型视频生成模型 胡锡进于2024年2月20日认为&#xff1a;台当局怂了 新的改变世界模拟器视觉数据转换视频压缩时空补丁&#xff08;Spacetime Laten Patches&#xff09;视频生成扩展变压器算法和模型架构结语 胡锡进于2024年2月20日认为&#xff1a;台当局怂了 **T…

[服务器-数据库]MongoDBv7.0.4不支持ipv6访问

文章目录 MongoDBv7.0.4不支持ipv6访问错误描述问题分析错误原因解决方式 MongoDBv7.0.4不支持ipv6访问 错误描述 报错如下描述 Cannot connect to MongoDB.No suitable servers found: serverSelectionTimeoutMS expired: [failed to resolve 2408]问题分析 首先确定其是…

最长回文子串------Manacher算法

​​​​​​​目录 一、问题 ​二、Manacher算法基本思想 三、manacher算法对称性中的计算 四、manacher算法代码 最长回文子串------Manacher算法 一、问题 最长连续回文子序列(longest continuous palindrome subsequence&#xff0c;LCPS)&#xff0c;给定序列A&#xff0…

【深度学习:对象跟踪】对象跟踪完整指南 [教程]

【深度学习&#xff1a;对象跟踪】对象跟踪完整指南 [教程] 什么是计算机视觉中的对象跟踪&#xff1f;对象跟踪有哪些不同类型&#xff1f;图像跟踪视频跟踪单目标跟踪多对象跟踪 计算机视觉中对象跟踪的用例监测零售自动驾驶汽车医疗保健 对象跟踪方法步骤 1&#xff1a;目标…

Flink双流(join)

一、介绍 Join大体分类只有两种&#xff1a;Window Join和Interval Join Window Join有可以根据Window的类型细分出3种&#xff1a;Tumbling(滚动) Window Join、Sliding(滑动) Window Join、Session(会话) Widnow Join。 &#x1f338;Window 类型的join都是利用window的机制…

mac 安装H3C iNode + accessClient mac版

一、下载安装 官网下载地址 https://www.h3c.com/cn/Service/Document_Software/Software_Download/IP_Management/ 可以使用文末参考博文中的账号 yx800 密码 01230123登录下载 选择版本 下载 下载 H3C_iNode_PC_7.3_E0626.zip 文件后&#xff0c;解压下载到的PC端压缩包…

linux单机巡检脚本并发送邮箱的巡检报告

#!/bin/bash # Author: HanWei # Date: 2020-03-16 09:56:57 # Last Modified by: HanWei # Last Modified time: 2020-03-16 11:06:31 # E-mail: han_wei_95163.com #!/bin/bash #安装mail yum -y install mailx#主机信息每日巡检IPADDR$(ifconfig eth0|grep inet addr|aw…

2023数据要素市场十大关键词

2023数据要素市场十大关键词 导读 2023年即将过去。一年之前&#xff0c;《中共中央国务院关于构建数据基础制度更好发挥数据要素作用的意见》&#xff08;简称“数据二十条”&#xff09;正式对外发布&#xff0c;为数据要素市场的建设举旗定向。 图片 2023年是“数据二十条…

python自动化接口测试

前几天&#xff0c;同组姐妹说想要对接口那些异常值进行测试&#xff0c;能否有自动化测试的方法。仔细想了一下&#xff0c;工具还挺多&#xff0c;大概分析了一下&#xff1a; 1、soapui:可以对接口参数进行异常值参数化&#xff0c;可以加断言&#xff0c;一般我们会加http…

Zabbix 6.2.1 安装

目录 1、监控介绍 监控的重要性 网站的可用性 监控范畴 如何监控 2、Zabbix 介绍 zabbix 简介 zabbix 主要功能 zabbix 监控范畴 Zabbix 监控组件 zabbix 常见进程 zabbix agentd 工作模式 zabbix 环境监控中概念 3、搭建LNMP 拓扑规划 安装MySQL 安装 Nginx …

【Vulkan Tutorials 01】【环境搭建】三角形例子

Development Environment&#xff08;开发环境&#xff09; 1. 安装Vulkan SDK 官网 2. 安装cmake和minGW 2.1 cmake 官网 双击可执行文件&#xff0c;然后直接安装&#xff0c;注意环境变量选择设置&#xff0c;否则需要自己操作。 2.2 minGW 官网 下载如下图所示&am…

Qt应用-天气预报实例

本文讲解Qt实现天气预报实例。 实现的功能 网络实时获取和显示6天的天气参数并绘制温度趋势曲线; 测试当前网络连接情况; 获得当前的IP地址的行政位置信息; 设计界面如下: 创建保存天气数据的类 #ifndef WEATHERDATA_H #define WEATHERDATA_H #include <QString>…

如何使用ArcGIS Pro生成等高线

无论在制图还是规划中&#xff0c;经常会使用到等高线&#xff0c;大多数情况下&#xff0c;从网上获取的高程数据都是DEM文件&#xff0c;我们可以通过ArcGIS Pro来生成等高线&#xff0c;这里为大家介绍一下生成方法&#xff0c;希望能对你有所帮助。 数据来源 教程所使用的…

【转载】企业资产收集与脆弱性检查工具

简介 云图极速版是针对拥有攻击面管理需求的用户打造的 SaaS 应用&#xff0c;致力于协助用户管理互联网资产攻击面的 SaaS 化订阅服务产品。可实现对备案域名、子域名、IP、端口、服务、网站、漏洞、安全风险等场景进行周期性监控&#xff0c;支持多维度分析攻击面。利用可视化…

下一代自动化爬虫神器--playwright,所见即所得,配合逆向不要太香!!!

文章目录 1.Playwright介绍2.与 Selenium 和 pyppeteer 相比&#xff0c;Playwright 具有以下几个区别和优势3.在爬虫中使用 Playwright 的好处4.环境安装5.屏幕录制6.保留记录cookie信息7.playwright代码编写详解1.第一个Playwright脚本&#xff08;1&#xff09;同步模式&…

小米标准模组+MCU 快速上手开发(二)——之模组串口调试

小米标准模组MCU 开发笔记之固件调试 背景技术名词简介● 小米IoT开发者平台● 小米IoT 模组● 固件● OTA● CRC32 固件双串口调试● MHCWB6S-IB 模组资料下载● MHCWB6S-IB 模组管脚图● 上电调试 背景 小米标准模组MCU的开发过程中&#xff0c;由于部分官方资料较为古早&am…

解决MobaXterm网络错误连接超时问题

报错页面&#xff1a; 报错原因&#xff1a; ①网络断开了 ②网络端口&#xff0c;端口号改变 解决办法&#xff1a; ①重新连接网络按R ②固定端口号 第一步&#xff1a;编辑------>虚拟机网络编辑器&#xff08;我的Linux在虚拟机里&#xff09; 第二步&#xff1a;用…

【触想智能】工业平板知识分享|选购工业平板电脑需要注意的7大事项

工业平板电脑是一种将显示器、工控主板、触摸屏和其他电子设备整合在一起的电子产品。它广泛应用于工业控制和自动化领域。 在购买工业平板电脑时&#xff0c;需要考虑一些关键性因素&#xff0c;以确保工业平板电脑是安全可靠、运行稳定的。那么我们在购买工业平板电脑的时候&…

js设计模式:计算属性模式

作用: 将对象中的某些值与其他值进行关联,根据其他值来计算该值的结果 vue中的计算属性就是很经典的例子 示例: let nowDate 2023const wjtInfo {brithDate:1995,get age(){return nowDate-this.brithDate}}console.log(wjtInfo.age,wjt年龄)nowDate 1console.log(wjtInf…

5 原型模式 Prototype

1.模式定义: 指原型实例指定创建对象的种类&#xff0c;并且通过拷贝这些原型创建新的对象 2.应用场景&#xff1a; 当代码不应该依赖于需要复制的对象的具体类时&#xff0c;请使用Prototype模式。 Spring源码中的应用 org.springframework.beans.factory.support.AbstractB…