Java原理学习⭐

5. Java知识补充⭐

5.1 什么是构造方法⭐

## 构造方法的特点:
## 第一,构造方法必须与类同名,来告诉程序,它是一个构造方法
## 第二,在加载一个类时,会先加载构造方法
## 第三,构造方法,没有返回值
/*构造方法是什么意思?

构造方法(也称为构造函数)是一种特殊类型的方法,用于在创建对象时初始化对象的状态。在Java中,构造方法具有以下特
与类名相同:构造方法的名称必须与定义它的类的名称完全相同。
没有返回类型:与类中的其他方法不同,构造方法没有返回类型(包括void)。
自动调用:当你使用new关键字创建类的一个新实例时,构造方法会被自动调用。
重载:一个类可以有多个构造方法,只要它们的参数列表不同(这称为构造方法的重载)。
初始化对象:构造方法通常用于设置对象的初始状态,例如分配内存、给实例变量赋初值等。

下面是一个简单的Java类示例,其中包含了一个无参数的构造方法和一个带参数的构造方法:*/

public class Person {  
    private String name;  
    private int age;  
  
    // 无参数的构造方法  
    public Person() {  
        this.name = "Unknown";  
        this.age = 0;  
    }  
  
    // 带参数的构造方法  
    public Person(String name, int age) {  
        this.name = name;  
        this.age = age;  
    }  
  
    // 其他方法,如getters和setters等...  
    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;  
    }  
}

5.2 MVC架构的理解⭐

## MVC的理解,可以从顺序来梳理
## MVC:model层,view层,Controller层
## 第一步:用户通过view层,进行数据请求
## 第二步:数据请求通过Controller层,进行合理性评估,在调用model层中,Service层接口
## 第三步:Service层接口,调用DAO层的数据,并进行数据业务逻辑加工
## 第四步:Service层接口将加工后的数据,返回给Controller层
## 第五步:Controller层返回给view层

## 所以顺序大致为view-->Controller-->model(Service)-->model(DAO),再沿路返回
顺序差不多是数据访问层,业务逻辑,验证逻辑,服务接口定义,Controller层,view层,对吗?

顺序上,你提到的这些组件或层在Web应用程序中的排列并不是完全按照执行流程来排列的,而是按照它们在应用程序架构中的逻辑位置和功能来区分的。不过,我们可以按照它们在处理用户请求时的逻辑顺序来大致描述它们的关系。

以下是这些组件或层在逻辑上的一种常见顺序:

View层:首先,用户通过浏览器或其他客户端与View层交互,这是用户界面的展现层。

Controller层:用户的请求(如点击按钮、提交表单等)首先到达Controller层。Controller层负责接收请求,并根据请求的类型和内容调用相应的业务逻辑。

Service层(业务逻辑层):Controller层调用Service层的业务逻辑来处理用户的请求。Service层可能包含多个服务接口定义及其实现,这些服务封装了具体的业务逻辑。

验证逻辑:在Service层处理业务逻辑之前或过程中,通常会有验证逻辑来检查输入数据的合法性和有效性。验证逻辑可以作为Service层的一部分,也可以单独作为一个组件。

数据访问层(DAO层):Service层在处理业务逻辑时,如果需要与数据库交互,会调用数据访问层(DAO层)来执行数据的增删改查操作。DAO层封装了与数据库交互的细节。

数据模型(Data Model):数据模型是应用程序中数据的表示,通常与数据库中的表相对应。它们用于在应用程序中传输和存储数据。

请注意,这个顺序更多的是一个逻辑上的顺序,用于描述这些组件或层在处理用户请求时的交互和依赖关系。在实际应用中,这些组件或层之间的交互可能更加复杂和交错,特别是在异步处理、事件驱动等复杂场景中。

另外,验证逻辑的位置可能会因具体实现而有所不同。有些项目中,验证逻辑可能放在Controller层进行初步验证,然后在Service层进行更深入的验证。这取决于项目的具体需求和团队的约定。

总的来说,重要的是理解这些组件或层在应用程序架构中的职责和关系,以便能够合理地组织代码和实现高效的业务逻辑处理。

5.3 Java的特性⭐⭐⭐

Java是一种广泛使用的编程语言,它具有许多显著的特性,这些特性使得Java成为软件开发领域的首选语言之一。以下是Java的一些主要特性:

  1. 面向对象:Java是一种纯面向对象的语言,这意味着Java程序由对象组成,这些对象具有状态和行为。Java支持类、继承、封装和多态等面向对象编程的基本概念。
  2. 平台无关性(跨平台性):Java的“一次编写,到处运行”的能力是其最显著的特性之一。这是通过Java虚拟机(JVM)实现的,JVM能够在不同的操作系统上运行,从而使得Java程序可以在任何安装了JVM的平台上运行。
  3. 自动内存管理:Java具有自动内存管理功能,包括垃圾回收机制,这有助于减少内存泄漏和内存管理错误。
  4. 丰富的API:Java拥有大量的标准库和API,涵盖了从基本输入/输出到网络编程、数据库访问、图形用户界面开发等各个方面,为开发者提供了极大的便利。
  5. 多线程支持:Java内置对多线程的支持,这使得开发并发和多线程应用程序变得相对简单。
  6. 安全性:Java设计之初就考虑到了安全性,它提供了许多内置的安全特性,如访问控制、加密API等,使得Java成为开发安全敏感应用程序的理想选择。
  7. 泛型编程:Java支持泛型编程,允许在定义类、接口和方法时使用类型参数,从而提高了代码的重用性和类型安全性。
  8. 注解(Annotations):Java 5引入了注解功能,它允许开发者为代码添加元数据,从而简化了某些编程任务,如配置、测试等。
  9. Lambda表达式和函数式接口:从Java 8开始,Java支持Lambda表达式和函数式接口,这使得Java能够更简洁地表达函数式编程的概念,并简化了某些常见任务的实现。
  10. 模块化:从Java 9开始,Java引入了模块化系统,这有助于减少应用程序的启动时间、提高安全性并简化依赖管理。

这些特性使得Java成为一种强大、灵活且易于使用的编程语言,适用于各种规模的应用程序开发。

5.4.1 面向对象的理解

5.4.1.1 类的理解

类class:万物抽象为了一个实体(class,例如:Person),然后将这个(Person),构建出静态属性(例如age,name)+动态方法(跑,跳,吃,介绍自己)

// 定义一个名为Person的类  

public class Person {  
    // 属性或成员变量  
    String name;  
    int age;  
      
    // 方法或成员函数  
    public void introduce() {  
        System.out.println("My name is " + name + " and I am " + age + " years old.");  
    }  
} 

5.4.1.2 继承的理解

继承Inheritance的特点

  • 代码复用:一次编写,多次复用的实现,例如(介绍自己introduce方法,和属性studentId)
  • 复用的同时:保证可扩展性,例如:方法study()的新增,和对introduce()的重写
// 定义一个Student类,继承自Person类  

public class Student extends Person {  
    // 学生特有的属性  
    String studentId;  
      
    // 学生特有的方法  
    public void study() {  
        System.out.println("Studying hard...");  
    }  
      
    // 重写父类的方法(可选)  
    @Override  
    public void introduce() {  
        System.out.println("I am a student. My name is " + name + " and I am " + age + " years old.");  
    }  
} 

5.4.1.3 封装的理解

封装 (Encapsulation): 封装将数据(变量)和对数据的操作(方法)绑定在一起,作为一个单独的对象。通过封装,可以隐藏对象的内部状态和实现细节,只对外暴露有限的接口。

public class EncapsulatedPerson {  
    // 私有成员变量,只能通过公共方法进行访问和修改  
    private String name;  
    private int age;  
      
    // 公共构造函数,用于初始化对象  
    public EncapsulatedPerson(String name, int age) {  
        this.name = name;  
        this.age = age;  
    }  
      
    // 公共getter和setter方法,用于访问和修改私有成员变量  
    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;  
    }  
      
    // 公共方法,用于介绍自己  
    public void introduce() {  
        System.out.println("My name is " + name + " and I am " + age + " years old.");  
    }  
}

5.4.1.4 多态的理解

多态 (Polymorphism): 主要用于继承中,当父类需要使用子类的功能时,可以通过类型转换,直接转换为子类,使用子类的属性和方法,例如:((Student) people[1]).studentId = "S123"; 中people使用转换为Student类,并使用其属性studentId

public class PolymorphismDemo {  
    public static void main(String[] args) {  
        // 创建一个Person数组,但可以存储Person和它的子类的对象
        Person[] people = new Person[2];

        // 创建Person对象
        people[0] = new Person();
        people[0].name = "Alice";
        people[0].age = 30;

        // 创建Student对象,并存储在Person数组中(多态)
        people[1] = new Student();
        people[1].name = "Bob";
        people[1].age = 20;
        ((Student) people[1]).studentId = "S123"; // 强制类型转换以访问Student的特有属性

        // 调用每个人的introduce方法,将展示不同的行为(多态的体现)
        for (Person person : people) {
            person.introduce();
        }  
    }  
}

5.4.2 虚拟机jvm的理解

## 要理解jvm虚拟机,首先要理解它的组成
## 1. 类加载器(Class Loader):负责加载类,到jvm虚拟机中,我把它类比为光驱,类则是光盘
## 2. 运行时数据区(Runtime Data Area):运行时数据区,我把它类比为主机,其中包括多个部分
###  2.1 方法区(Method Area):可以类比为硬盘,存储类如加载的类等信息
###  2.2 堆(Heap):可以类比为内存,用于存放新建对象的实例。
###  2.3 栈(Stack):可以类比为cpu的一部分,每个线程都会建立一个对应的栈,用于存储局部变量、动态链接、方法出口等信息
###  2.4 程序计数器(Program Counter Register): 可以类比为cpu的一部分,用于记录代码执行的位置(比如:记录行数位置)
###  2.5 本地方法栈(Native Method Stack):可以类比为cpu的一部分,类似于栈(Stack),主要用于使用本地方法,而不是java方法

## 3. 执行引擎(Execution Engine):两种执行模式,一是逐条编译并执行,二是全部编译后,存储到运行时数据区再执行
## 4. 本地方法接口(Native Method Interface):调用非Java代码的接口,例如,Java的native方法就是用C/C++编写的,并通过本地方法接口(本地方法栈中)在Java虚拟机内部执行,
## 5. 垃圾收集器(Garbage Collector):自动回收不再使用的对象,由多种算法实现

5.4.3 内存管理的理解

## java内存管理的理解
## 1. 开辟内存空间,通常在创建对象时开辟(例如:MyClass obj = new MyClass();int[] arr = new int[10];Integer num = 123;String str1 = "hello"; )
## 2. 垃圾回收,通常由几个条件会出现垃圾回收
## 2.1 内存占用达到阈值
## 2.2 调用System.gc()方法
## 2.3 内存分配失败
## 2.4 空闲时间长
## 2.5 Full GC触发:在某些情况下,例如永久代满、CMS垃圾回收器的并发失败等,会触发Full GC,对整个堆进行垃圾回收。
垃圾回收算法的引申(了解即可):

垃圾收集器(Garbage Collector)在Java虚拟机中负责自动回收不再使用的对象所占用的内存。垃圾收集器实现的算法有很多种,每一种都有其特定的适用场景和优缺点。以下是一些常见的垃圾收集器算法:

标记-清除(Mark-Sweep)算法:
标记阶段:从根对象(如静态变量、线程栈中的局部变量等)开始递归地访问对象的引用链,将所有可达对象都标记为存活。
清除阶段:遍历整个堆内存,将未被标记的对象(即不可达对象)回收掉。
优缺点:标记-清除算法实现简单,但缺点是会产生内存碎片,影响内存分配效率。
复制(Copying)算法:
将可用内存划分为大小相等的两块,每次只使用其中一块。当这一块内存用完时,就将还存活的对象复制到另一块上面,然后再把已使用过的内存空间一次清理掉。
优缺点:实现简单,效率高,且不会产生内存碎片。但缺点是可用内存缩小为原来的一半。因此,这种算法通常用于新生代的垃圾收集。
标记-整理(Mark-Compact)算法:
标记阶段与标记-清除算法相同,但清除阶段不是直接对未标记的内存进行回收,而是让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存。
优缺点:解决了内存碎片问题,但效率相对标记-清除算法较低。
分代收集(Generational Collection)算法:
根据对象存活周期的不同将内存划分为几块。一般是把Java堆分为新生代和老年代,这样就可以根据各个年代的特点采用最适当的收集算法。在新生代中,每次垃圾收集时都发现有大批对象死去,只有少量存活,那就选用复制算法,只需要付出少量存活对象的复制成本就可以完成收集。而老年代中因为对象存活率高、没有额外空间对它进行分配担保,就必须使用“标记-清除”或者“标记-整理”算法来进行回收。
分区算法:
将整个堆空间划分为连续的不同小区间,每一个小区间都独立使用,独立回收。这种算法的好处是可以控制一次回收多少个小区间,从而控制一次停顿的时间;但是缺点是存在内存使用效率不高的问题。
不同的垃圾收集器可能采用不同的算法,并且结合其他的优化手段来平衡收集效率、内存利用率以及停顿时间等因素。在实际应用中,Java虚拟机通常会提供多种垃圾收集器供用户选择,以满足不同的性能需求。

5.4.4 Java泛型的理解

// 理解泛型,首先看一个基本的泛型使用

public class Box<T> {  
    private T t;  
  
    public void set(T t) {  
        this.t = t;  
    }  
  
    public T get() {  
        return t;  
    }  
}

// 这里面的T,代表任意类型的参数,即T可以是Int,String,也可以是Float
// 还需要注意的是,<>没有参数的和使用,例如:
KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);

// 这是代表这里的 KafkaConsumer 是一个泛型类,它接受两个类型参数:键(Key)的类型和值(Value)的类型。
// 第一个类型参数 String 代表从Kafka主题中读取的消息的键的类型。
// 第二个类型参数 String 代表从Kafka主题中读取的消息的值的类型。

// 尖括号 <> 中没有包含类型参数时,触发'类型推断'特性,表示编译器会尝试根据上下文来自动推断这些类型参数的具体类型。如果不能成功推断,编译器可能会报错或要求你显式提供这些类型。

5.4.5 注解的理解

5.4.5.1 注解理解⭐

## 1. 首先要理解注解,先要理解spring框架的几个特性
## 第一是:反转控制,简而言之就是,省去自己创建实例的步骤,在启动项目时,由框架自己创建实例(beanFactory创建ben,bean中包含实例)
## 第二是:依赖注入,即在创建bean时,会加入其中实例所有的依赖部分
## 第三是:面向AOP编程,即拿出复用、常用的一些功能,由框架自带,或者通过注解功能,用户自己编写,做到一次编写,多次复用的效果

## 2. 所以,注解其实有几个作用
## 第一是:反转控制时,即在创建bean时,,告诉框架,哪些自己创建的类,需要创建成为bean(向框架进行注册,例如:@Component、@Autowired)
## 第二是:告诉框架,类之间的依赖关系,方便依赖注入(例如:@Component、@Autowired)
## 第三是:调用这些复用的类(框架自带的类,例如日志记录、性能监控、事务管理、安全性检查),或者向框架注册自己的类,并反复调用

## 综上,在spring框架的运用中,对注解更好的理解与熟练使用常用注解,就尤为重要

5.4.5.2 常用注解(待使用/更新)

1. @Component

   - 说明:泛指各种组件,当类不属于@Controller、@Service、@Repository等特定分类时,可以使用此注解。它告诉Spring这是一个Bean,需要被Spring容器管理。

   - 示例:

     ```java
     @Component  
     public class MyComponent {  
         // ...  
     }
     ```

2. @Service

   - 说明:用于标注业务逻辑层(Service层)的组件。

   - 示例:

     ```java
     @Service  
     public class MyService {  
         // ...  
     }
     ```

3. @Repository

   - 说明:用于标注数据访问层(DAO层)的组件,通常与数据库交互。

   - 示例:

     ```java
     @Repository  
     public class MyRepository {  
         // ...  
     }
     ```

4. @Controller

   - 说明:用于标注MVC结构中的控制器组件,通常处理HTTP请求。

   - 示例:

     ```java
     @Controller  
     public class MyController {  
         // ...  
     }
     ```

5. @Autowired

   - 说明:用于自动装配Bean,可以简化依赖注入的配置。

   - 示例:

     ```java
     @Service  
     public class MyService {  
         @Autowired  
         private MyRepository myRepository;  
         // ...  
     }
     ```

6. @Value

   - 说明:用于注入配置文件中的值或表达式的结果。

   - 示例:

     ```java
     @Component  
     public class MyComponent {  
         @Value("${some.property}")  
         private String someProperty;  
         // ...  
     }
     ```

7. @Configuration

   - 说明:用于标识一个类作为配置类,该类中可以定义Bean。

   - 示例:

     ```java
     @Configuration  
     public class AppConfig {  
         @Bean  
         public MyComponent myComponent() {  
             return new MyComponent();  
         }  
     }
     ```

8. @Bean

   - 说明:用于声明一个由Spring容器管理的Bean。通常与@Configuration一起使用。
   - 示例:见上面的@Configuration示例中的`myComponent`方法。

9. @Qualifier

   - 说明:当存在多个同类型的Bean时,可以使用@Qualifier来指定注入哪一个Bean。

   - 示例:

     ```java
     @Autowired  
     @Qualifier("specificBean")  
     private MyBean myBean;
     ```

10. @Transactional

    - 说明:用于声明事务管理,可以确保一系列数据库操作要么全部成功,要么全部失败(回滚)。

    - 示例:

      ```java
      @Service  
      @Transactional  
      public class MyTransactionalService {  
          // ...  
      }
      ```

## 
posted @ 2024-04-23 16:12  付十一。  阅读(15)  评论(0)    收藏  举报