JavaRush /Java 博客 /Random-ZH /喝咖啡休息#121。Java中的Classpath是什么以及如何安装它?Java 中的不变性

喝咖啡休息#121。Java中的Classpath是什么以及如何安装它?Java 中的不变性

已在 Random-ZH 群组中发布

Java中的Classpath是什么以及如何安装它?

来源:Medium 了解编程基础知识和程序文件的执行流程有助于我们理解一门语言。了解Classpath参数是每个Java开发人员都应该了解的基本概念之一。今天我们将讨论什么是类路径(Classpath)、如何设置它以及它如何帮助 JVM 执行类文件。 喝咖啡休息#121。 Java中的Classpath是什么以及如何安装它? Java 中的不变性 - 1

什么是类路径?

类路径是Java中的基本参数之一,但它经常被编程新手误解。简单来说,类路径只是一组路径,Java 编译器和 JVM 必须沿着这些路径找到编译或执行其他类所需的类。

Classpath 如何帮助 JVM 执行类文件

让我们从一个例子开始。假设我们有一个Main.java文件,位于/Users/vikram/Documents/test-java/src/com/programming/v1/Main.java文件夹中。
package com.programming.v1;

public class Main {
    public static void main(String[] args) {
        System.out.println("Hello classpath");
    }
}
假设我们位于/Users/vikram/Documents中并且想要编译此类:
javac test-java/src/com/programming/v1/Main.java
现在,要执行这个类文件,我们需要使用类路径java命令中的cp标志 告诉 Java 虚拟机在哪里查找.class文件。
vg@lp1 Documents % java -cp "test-java/src" com.programming.v1.Main
Hello classpath
vg@lp1 Documents % java -classpath "test-java/src" com.programming.v1.Main
Hello classpath
第一个参数是写入包的根文件夹。第二个参数是包名和类名。当执行Java命令时,Java虚拟机会查找test-java/src文件夹,然后加载主类来执行它。

如何设置类路径变量

在 Linux 机器上,可以按如下所示设置 Classpath变量:
export CLASSPATH="test-java/src"
可以使用环境变量添加/更新 Windows 计算机上的类路径。 设置好环境变量后,就可以执行java命令了,如下所示:
vg@lp1 Documents % java com.programming.v1.Main
Hello classpath
这就是关于Classpath 的 全部信息。感谢您的阅读!

Java 中的不变性

来源:Medium Java 中的变量有两种类型:原始变量和引用变量。Java 中的所有内容都是按值传递的,但在引用类型的情况下,可以使用传递的内存地址来更新源数据。 Final喝咖啡休息#121。 Java中的Classpath是什么以及如何安装它? Java 中的不变性 - 2关键字用于使变量充当常量,即避免重新赋值。这对于没有堆内存的基元非常有效,而对于引用类型,仅重新分配受到限制并且内部状态可以更改。这可能会导致许多并发问题和竞争条件。因此,在 Java 的常规类型中包含不可变特性提供了许多好处。

Java 中不变性的好处

1. 线程安全

不可变类型不受多线程环境中竞争条件的影响,因为对象在创建后将保持一致。多个线程无法更改其内部状态,因此不需要同步。

2. 基本型

Java 标准库中的String是基类的一个很好的例子。这是一个非常简单且不可变的类,可用于在其之上构建业务逻辑域。同样,不可变类型可以作为构建的基础类型。

特征

1. Private 和 Final 字段

包含对象状态的字段是privateFinal。私有可见性可防止直接访问该字段,而最终可见性可确保字段仅分配一次。

2.无修饰方法

私有字段不能在类外部访问。通常,分别提供访问方法(getter)和修饰符方法(setter)来读取和写入字段。为了确保一致性,不允许使用修饰符。

3.最后一堂课

允许类继承可能会破坏不变性。扩展不可变类的子类可以影响对象的状态。因此,该课程是最终的

4. 防御性副本

在对象创建期间,不是将构造函数中的参数直接分配给私有字段,而是创建参数的深层副本(或不可变副本)将提供外部修改。如果参数之一是引用类型,则可以在调用方端轻松对其进行操作。创建保护副本可以让您避免这种操作。类似地,对于访问器(getters),不是直接引用内部字段,而是可以自由共享它的副本。

执行

员工

import java.time.LocalDate;
import java.util.List;

import static java.util.List.copyOf;

public final class Employee {

    private final long id;
    private final String name;
    private final LocalDate joinDate;
    private final List<String> achievements;

    public Employee(long id,
                    String name,
                    LocalDate joinDate,
                    List<String> achievements) {
        this.id = id;
        this.name = name;
        this.joinDate = joinDate;
        this.achievements = copyOf(achievements);
    }

    public long getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public LocalDate getJoinDate() {
        return joinDate;
    }

    public List<String> getAchievements() {
        return achievements;
    }
}
  • 并非所有字段在构造函数中都有保护副本。这是因为id是原始类型,而namejoinDate字段是不可变类型。它们不能被调用者更改并且将保持不变,而成就字段需要使用List.copyOf方法创建的参数的副本。这是因为copyOf返回一个不可变的List

  • 同样,访问器方法直接返回字段而不是防御性副本,因为所有字段类型都是不可变的(包括成就),因此不能在类外部进行修改。

改进

Java 16 之前

可以使用Lombok等库来改进Employee实现。这减少了代码的冗长并帮助它看起来更干净。该库附带注释以缩短标准代码。@Value(注释)可用于为所有参数创建 getter 和构造函数。这还创建了一个最终类以及私有最终字段。需要注意的是,它还生成toStringequalshashCode方法。可以使用@Value重写Employee实现,如下所示:
import lombok.Value;

import java.time.LocalDate;
import java.util.List;

import static java.util.List.copyOf;

@Value
public class Employee {

    long id;
    String name;
    LocalDate joinDate;
    List<String> achievements;

    public Employee(long id,
                    String name,
                    LocalDate joinDate,
                    List<String> achievements) {
        this.id = id;
        this.name = name;
        this.joinDate = joinDate;
        this.achievements = copyOf(achievements);
    }
}

Java 16 及更高版本

Java 16 版本引入了新的Record函数。这些(如 JEP 所述)是充当不可变数据的透明载体的类,并且可以被视为名义元组。Employee类可以重新实现为记录 Employee,如下所示。
import java.time.LocalDate;
import java.util.List;

import static java.util.List.copyOf;

public record Employee(long id,
                       String name,
                       LocalDate joinDate,
                       List<String> achievements) {

    public Employee(long id,
                    String name,
                    LocalDate joinDate,
                    List<String> achievements) {
        this.id = id;
        this.name = name;
        this.joinDate = joinDate;
        this.achievements = copyOf(achievements);
    }
}

缺陷

不变性的唯一问题是即使是很小的修改也需要额外的内存和处理。每次都需要创建一个新对象,这可能非常昂贵。为了解决这个缺点,您可以实现缓存和保存结果等机制。
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION