HarmonyOS提供了ArkTS(Ark TypeScript)作为JavaScript的一个超集,允许开发者编写更加类型安全的代码。本篇技术文章将重点对比Java与ArkTS中的方法重载以及数值类型的使用差异,并介绍如何处理超大数字数据,保持精度。

【1】方法重载

在Java中,方法重载是指同一个类中有多个同名的方法,但是参数列表不同。而在ArkTS中,由于静态类型检查的限制,不能直接支持方法重载。不过,可以通过其他方式来模拟这种行为。

Java 示例

public class NumberService {
    public void displayMessage() {
        System.out.println("No arguments");
    }

    public void displayMessage(String name) {
        System.out.println("With argument: " + name);
    }
}

public class Main {
    public static void main(String[] args) {
        NumberService service = new NumberService();
        service.displayMessage();
        service.displayMessage("John Doe");
    }
}

ArkTS 示例

class NumberService {
  displayMessage(name?: string) {
    if (name) {
      console.log(`With argument: ${name}`);
    } else {
      console.log("No arguments");
    }
  }
}

const service = new NumberService();
service.displayMessage();
service.displayMessage("John Doe");

对于不同类型参数的重载,可以使用联合类型|来模拟:

class NumberService {
  displayMessage(value: string | number) {
    if (typeof value === 'number') {
      console.log(`Number argument: ${value}`);
    } else {
      console.log(`String argument: ${value}`);
    }
  }
}

const service = new NumberService();
service.displayMessage(42);
service.displayMessage("Hello");

对于参数数量不同的情况,可以使用默认参数或可选参数来处理:

class NumberService {
  displayMessage(filePath: string, fileName: string = "", value: string) {
    if (!fileName) {
      console.log(`Single path: ${filePath}, value: ${value}`);
    } else {
      console.log(`Path and file name: ${filePath}, ${fileName}, value: ${value}`);
    }
  }
}

const service = new NumberService();
service.displayMessage("path/to/file", "", "content");
service.displayMessage("path/to/directory", "file.txt", "content");

【2】数值类型对比

Java与ArkTS在处理数值类型上有所不同,特别是对于大整数的支持。下面将分别介绍Java中的byte、BigInteger,以及ArkTS中的number、BigInt、Uint8Array、Int8Array。

Java 示例

public class Main {
    public static void main(String[] args) {
        // Java byte,范围:-128 到 127
        byte javaByte = 127;
        System.out.println("Java byte: " + javaByte);

        // 对于非常大的数字,Java 需要使用 BigInteger
        BigInteger bigInt = new BigInteger("1234567890123456789012345678901234567890");
        System.out.println("BigInteger(用于非常大的数字):" + bigInt);

        // Java 没有直接等价于 Uint8Array 的类型,但可以使用 byte[] 并进行转换
        byte[] asciiBytes = "Hello".getBytes(StandardCharsets.US_ASCII);
        System.out.print("ASCII 字节(类似于 TypeScript 的 Uint8Array):");
        for (byte b : asciiBytes) {
            System.out.print(b + " ");
        }
        System.out.println();

        // 直接使用 byte(有符号)类似于 TypeScript 的 Int8Array
        byte[] signedBytes = {127, -128, 64, -3};
        System.out.print("有符号字节:");
        for (byte b : signedBytes) {
            System.out.print(b + " ");
        }
        System.out.println();
    }
}

ArkTS 示例

// 使用Number类型,超过安全整数范围会丢失精度
let num = 1234567890123456789012345678901234567890;
console.log("number (may lose precision):", num);

// BigInt类型,用于精确表示极大或极小整数
let bigIntNum = BigInt("1234567890123456789012345678901234567890");
console.log("BigInt (precise for very large numbers):", bigIntNum);

// Uint8Array,无符号8位整数数组
let byteArray = new Uint8Array([72, 101, 108, 108, 111]); // Hello 的ASCII编码
console.log("Uint8Array (unsigned bytes for ASCII encoding):", byteArray);
console.log("Uint8Array 内容转换为字符串:", String.fromCharCode(...byteArray));

// Int8Array,有符号8位整数数组
let signedByteArray = new Int8Array([127, -128, 64, -3]);
console.log("Int8Array (signed bytes, similar to Java's byte):", signedByteArray);

【3】处理超大数字数据与精度保持

在HarmonyOS应用中处理超大数字数据时,如果数据是整数,可以使用BigInt类型来保持精度。如果数据带有小数部分,可以借助第三方库如decimal.js中的Decimal类型来处理。

Java 示例

import java.math.BigDecimal;

public class Main {
    public static void main(String[] args) {
        // 使用BigDecimal处理带小数的大数字
        BigDecimal decimalNumber = new BigDecimal("9999999999999999999999999999999999999999999999999999999999999.123456");
        System.out.println("BigDecimal (fixed-point arithmetic): " + decimalNumber.toString());
    }
}

打印结果

BigDecimal (fixed-point arithmetic): 9999999999999999999999999999999999999999999999999999999999999.123456

ArkTS 示例

导三方库命令

ohpm install decimal.js

代码

import Decimal from 'decimal.js';

@Entry
@Component
struct Page058 {
  build() {
    Column() {
      Button('测试')
        .fontSize(50)
        .fontWeight(FontWeight.Bold)
        .onClick(() => {
          let bigInteger: BigInt = BigInt("9999999999999999999999999999999999999999999999999999999999999");
          console.info('BigInteger', bigInteger);

          let decimalNumber = new Decimal("9999999999999999999999999999999999999999999999999999999999999.123456");
          console.info('DecimalNumber.toFixed(20)', decimalNumber.toFixed(20));
        })
    }
    .width('100%')
    .height('100%')
  }
}

打印结果

app Log: BigInteger 9999999999999999999999999999999999999999999999999999999999999
app Log: DecimalNumber.toFixed(20) 9999999999999999999999999999999999999999999999999999999999999.12345600000000000000

【结论】

通过上述对比可以看出,虽然Java与ArkTS在方法重载和数值类型的处理上有所不同,但都可以通过合理的编程实践达到类似的效果。在ArkTS中,通过使用可选参数、联合类型以及默认参数等方式,可以有效地模拟方法重载。而对于数值类型,尽管Java提供了BigInteger来处理非常大的数字,而ArkTS则使用BigInt类型来保证大整数的精度。此外,对于字节数组的处理,Java使用byte[],而ArkTS使用Uint8Array和Int8Array来区分有符号和无符号的数据。

在处理超大数字数据时,BigInt适用于整数,而BigDecimal适用于需要高精度的小数。掌握这些差异和技巧有助于开发者在使用ArkTS进行HarmonyOS应用开发时,能够更加自如地应对各种需求。