跳到主要内容

2024-10-18

一言

我们是学生,学生就要有学生的样子。 --- 《JOJO的奇妙冒险》 · 你家炸了


Java String

Java 21 相比 Java 11,在 String 相关的操作方面增加了许多新特性和方法,这些新特性使得字符串操作更加方便和直观。以下是 Java 21 中新增的与 String 相关的重要特性和方法:

1. stripIndent() (Java 13)

  • 作用: 去除多行字符串中每一行的公共缩进,常用于文本块(Text Blocks)。
  • 示例:
    String text = """
    Hello,
    World!
    """;
    System.out.println(text.stripIndent());
    输出:
    Hello,
    World!

2. translateEscapes() (Java 15)

  • 作用: 将字符串中的转义序列转换为实际字符,例如将 \\n 转换为换行符。
  • 示例:
    String str = "Hello\\nWorld";
    System.out.println(str.translateEscapes());
    输出:
    Hello
    World

3. formatted() (Java 15)

  • 作用: 用于格式化字符串,类似于 String.format(),但是更加简洁。
  • 示例:
    String name = "John";
    String greeting = "Hello, %s".formatted(name);
    System.out.println(greeting);
    输出:
    Hello, John

4. indent(int n) (Java 12)

  • 作用: 给每一行添加或移除指定数量的空格缩进,正数表示添加缩进,负数表示移除缩进。
  • 示例:
    String text = "Hello\nWorld";
    System.out.println(text.indent(4));
    输出:
        Hello
    World

5. repeat(int count) (Java 11)

  • 作用: 重复当前字符串指定次数。
  • 示例:
    String str = "Hello ";
    System.out.println(str.repeat(3));
    输出:
    Hello Hello Hello 

6. isBlank() (Java 11)

  • 作用: 判断字符串是否为空或只包含空白字符。
  • 示例:
    String str = "   ";
    System.out.println(str.isBlank()); // true

7. lines() (Java 11)

  • 作用: 将字符串按行拆分为流(Stream)。
  • 示例:
    String text = "Hello\nWorld\nJava";
    text.lines().forEach(System.out::println);
    输出:
    Hello
    World
    Java

8. strip(), stripLeading(), stripTrailing() (Java 11)

  • 作用: 去除字符串的前后空白字符。strip() 使用的是 Unicode 标准,因此与 trim() 更加健壮。
  • 示例:
    String str = "   Hello World   ";
    System.out.println(str.strip()); // 去除前后空白
    System.out.println(str.stripLeading()); // 去除前导空白
    System.out.println(str.stripTrailing()); // 去除尾随空白

9. 文本块(Text Blocks) (Java 13, Java 15)

  • 作用: 使用 """ 定义多行字符串,文本块提供了更加简洁和易读的多行字符串编写方式。
  • 示例:
    String textBlock = """
    {
    "name": "John",
    "age": 30
    }
    """;
    System.out.println(textBlock);
    输出:
    {
    "name": "John",
    "age": 30
    }

10. String.stripIndent()String.transform() (Java 12)

  • 作用:
    • stripIndent():用于去除多行文本中的公共缩进。
    • transform(Function<String, R>):用于链式地对字符串进行操作。
  • 示例:
    String result = " Hello ".transform(String::strip);
    System.out.println(result); // 输出: "Hello"

11. StringTemplate (Java 21)

  • 作用: 引入了字符串模板(String Template),可以用 STR. 来定义具有占位符的字符串,提供更优雅的字符串插值方式。
  • 示例:
    String name = "Alice";
    int age = 25;
    String result = STR."Hello, \{name}. You are \{age} years old.".toString();
    System.out.println(result);
    输出:
    Hello, Alice. You are 25 years old.

总结

Java 21 相比 Java 11,主要新增了用于简化字符串操作和文本处理的工具,例如:

  • 文本块(Text Blocks)使多行字符串编写更简单。
  • 新的方法如 stripIndent()translateEscapes()formatted() 等提供了更加灵活的字符串处理能力。
  • Java 21 的 StringTemplate 提供了现代化的字符串插值方式,使得代码更加简洁、易读。

这些改进大大增强了 Java 处理字符串的能力,提升了开发效率。

Gradle maven-publish插件

在Kotlin DSL语法的 build.gradle.kts 文件中配置 maven-publish 插件,可以按照以下步骤进行设置:

  1. plugins 块中引入 maven-publish 插件。
  2. 配置 publishing 块来设置发布的内容和目标。

以下是一个完整的示例:

plugins {
kotlin("jvm") version "1.9.0" // 示例:引入Kotlin插件
`maven-publish` // 引入 maven-publish 插件
}

group = "com.example"
version = "1.0.0"

java {
withJavadocJar()
withSourcesJar()
}

publishing {
publications {
create<MavenPublication>("mavenJava") {
from(components["java"]) // 发布 Java 组件

// 可选:设置 POM 信息
pom {
name.set("My Library")
description.set("A description of my library")
url.set("https://github.com/example/my-library")

licenses {
license {
name.set("The Apache License, Version 2.0")
url.set("http://www.apache.org/licenses/LICENSE-2.0.txt")
}
}
developers {
developer {
id.set("example")
name.set("Developer Name")
email.set("developer@example.com")
}
}
scm {
connection.set("scm:git:git://github.com/example/my-library.git")
developerConnection.set("scm:git:ssh://github.com:example/my-library.git")
url.set("https://github.com/example/my-library")
}
}
}
}

repositories {
maven {
val releasesRepoUrl = uri("https://your.repository.url/releases")
val snapshotsRepoUrl = uri("https://your.repository.url/snapshots")
url = if (version.toString().endsWith("SNAPSHOT")) snapshotsRepoUrl else releasesRepoUrl

credentials {
username = project.findProperty("repo.user") as String? ?: "defaultUser"
password = project.findProperty("repo.password") as String? ?: "defaultPassword"
}
}
}
}

说明:

  1. 插件配置:

    plugins {
    `maven-publish`
    }

    使用 maven-publish 插件来发布到 Maven 仓库。

  2. 发布的组件:

    from(components["java"])

    使用 from(components["java"]) 将 Java 组件发布出去,如果是 Kotlin 项目,你可以根据需要发布 kotlin 组件。

  3. 生成源代码和 Javadoc JAR:

    java {
    withJavadocJar()
    withSourcesJar()
    }

    这样可以生成包含 Javadoc 和源代码的 JAR 文件,便于开发者使用。

  4. POM 信息: 可以在 pom 块中配置项目的描述、开发者信息、许可证等元数据,这些信息会包含在生成的 POM.xml 文件中。

  5. 发布目标仓库:

    repositories {
    maven {
    val releasesRepoUrl = uri("https://your.repository.url/releases")
    val snapshotsRepoUrl = uri("https://your.repository.url/snapshots")
    url = if (version.toString().endsWith("SNAPSHOT")) snapshotsRepoUrl else releasesRepoUrl

    credentials {
    username = project.findProperty("repo.user") as String? ?: "defaultUser"
    password = project.findProperty("repo.password") as String? ?: "defaultPassword"
    }
    }
    }

    repositories 中配置发布的目标仓库,并根据版本号判断发布到 releasessnapshots 仓库。

这样配置后,你可以运行以下命令来发布你的库:

./gradlew publish

以上就是在 Kotlin DSL 中配置 maven-publish 插件的方法,希望对你有所帮助!

Gradle dependecies中 add()和addProvider()的区别

好的,我来详细解释一下 add()addProvider() 方法的区别,以及在您的代码中它们是如何使用的。

背景介绍

在 Gradle 中,DependencyHandler 提供了一系列方法用于向项目的配置中添加依赖项。常用的方法包括:

  • add(String configurationName, Object dependencyNotation)
  • addProvider(String configurationName, Provider<?> dependencyProvider)

这两个方法都用于向指定的配置添加依赖项,但它们在依赖项的处理方式和添加时机上有所不同。

add() 方法

add() 方法用于立即向指定的配置添加依赖项。其参数为:

  • configurationName:配置的名称(如 "implementation""testCompile" 等)。
  • dependencyNotation:依赖项的表示,可以是字符串(如 "org.apache.commons:commons-lang3:3.12.0")、项目对象、文件集合等。

当您调用 add() 方法时,Gradle 会立即解析并添加该依赖项。

示例:

project.getDependencies().add("implementation", "org.apache.commons:commons-lang3:3.12.0");

addProvider() 方法

addProvider() 方法用于延迟向配置添加依赖项。其参数为:

  • configurationName:配置的名称。
  • dependencyProvider:一个 Provider 对象,提供依赖项的表示。

使用 addProvider() 方法,依赖项的解析和添加会被延迟到 Gradle 实际需要这些信息的时候。这对于依赖项的信息在配置时还不确定,或者需要延迟计算的情况非常有用。

示例:

Provider<String> dependencyNotationProvider = someExtension.getVersion().map(version -> "org.example:library:" + version);
project.getDependencies().addProvider("implementation", dependencyNotationProvider);

代码中的具体应用

原始代码分析

project.getDependencies().addProvider(
jooqGeneratorRuntime.getName(),
jooqExtension.getEdition()
.map(e -> e.getGroupId() + ":jooq-codegen")
.flatMap(ga -> jooqExtension.getVersion().map(v -> ga + ":" + v))
);

在这段代码中:

  • 依赖项的构建是延迟的jooqExtension.getEdition()jooqExtension.getVersion() 都返回 Provider 对象,表示这些值可能在配置阶段还未确定,需要在之后的某个时间点(如执行任务时)才能确定。
  • 使用了 addProvider() 方法:因为依赖项的表示是一个 Provider<String>,所以需要使用 addProvider() 方法,以确保依赖项的解析和添加是延迟的。

添加当前项目作为依赖项

project.getDependencies().add(jooqGeneratorRuntime.getName(), project);

在这里:

  • 直接使用了 add() 方法:因为我们要添加的依赖项是当前的 project 对象,这个对象在配置阶段已经确定,不需要延迟计算。
  • 立即添加依赖项:由于依赖项已经确定,可以直接添加,不需要延迟。

为什么要区分 add()addProvider()

  1. 依赖项的可用性

    • 如果依赖项的所有信息在配置阶段已经确定(如固定的字符串或对象),可以直接使用 add() 方法。
    • 如果依赖项的信息需要在之后的某个时间点才能确定(如取决于其他任务的输出或用户的配置),应使用 addProvider() 方法。
  2. 延迟配置的优势

    • 使用 Provider 可以避免在配置阶段进行不必要的计算,提高构建的性能。
    • 可以确保依赖项的信息是最新的,尤其是在依赖项的版本或其他属性可能会变化的情况下。

总结

  • add() 方法:用于立即添加已知的依赖项。
  • addProvider() 方法:用于延迟添加依赖项,依赖项的信息由 Provider 提供,适用于依赖项信息在配置阶段尚未确定的情况。

在您的代码中,添加当前项目作为依赖项时,依赖项(project 对象)是已知的,因此使用 add() 方法。而在添加 jOOQ 的代码生成器依赖项时,依赖项的信息需要从 jooqExtension 中获取,并且这些信息可能在配置阶段尚未确定,因此使用 addProvider() 方法来延迟解析和添加依赖项。

希望这个解释能帮助您理解 add()addProvider() 的区别,以及它们在代码中的具体应用。