Published on

Java 开发者的 Dart 快速入门指南

Authors

基本结构和入口点

在 Java 中,主函数必须在类中定义,而 Dart 主函数可以独立存在。如下:

void main() {
  print('Hello, Dart!');
}

在 Java 中,入口点通常是这样的:

public class Main {
    public static void main(String[] args) {
        System.out.println("Hello, Java!");
    }
}

变量声明和类型系统

在 Java 中,变量声明需要指定类型,而 Dart 是一种类型推断语言,可以省略类型声明。如下:

int number = 42;
String text = "Hello, Java!";

从 Java 10 开始支持类型推断:

var number = 42;
var text = "Hello, Java!";

但是功能比较有限。

在 Dart 中,变量声明可以这样写:

var number = 42; // 类型推断
String text = "Hello, Dart!";
final constantText = "This is a constant"; // 常量
const anotherConstant = 3.14; // 编译时常量

Dart 中,默认是非 null 的类型,除非使用 ? 来表示可空类型:

int? nullableNumber; // 可空类型
String? nullableText; // 可空类型

这种做法可以最大限度的避免类型异常。

函数方法的定义

在 Java 中,方法定义需要指定返回类型和参数类型,而 Dart 的函数定义更为简洁。如下:

public int add(int a, int b) {
    return a + b;
}

在 Dart 中,可以这样写:

int add(int a, int b) {
  return a + b;
}

在 Dart 中,函数也可以是第一类对象,可以作为参数传递或返回。如下:

void main() {
  var result = calculate(5, 10, add);
  print(result); // 输出 15
}
int calculate(int a, int b, int Function(int, int) operation) {
  return operation(a, b);
}

Dart 支持位置参数和可选参数:

// name 是位置参数,必须按照位置传递
// greeting 是可选命名参数,可以不传递
// 如果不传递,默认值为 'Hello'
void greet(String name, {String greeting = 'Hello'}) {
  print('$greeting, $name!');
}
void main() {
  greet('Dart'); // 输出 "Hello, Dart!"
  greet('Dart', greeting: 'Welcome'); // 输出 "Welcome, Dart!"
}

用 [] 括起来表示可选位置参数,不传时使用默认值或为 null,如下:

void greet(String name, [int? age]) {
  if (age != null) {
    print('Hello $name, you are $age years old.');
  } else {
    print('Hello $name.');
  }
}

void main() {
  greet('Alice', 30); // 输出:Hello Alice, you are 30 years old.
  greet('Bob');       // 输出:Hello Bob.
}

你还可以为可选位置参数提供默认值:

void greet(String name, [int age = 18]) {
  print('Hello $name, you are $age years old.');
}

可选命名参数

使用 {} 括起来,允许参数以任意顺序传递,并且可以指定默认值:

void greet({required String name, int age = 18}) {
  print('Hello $name, you are $age years old.');
}

可以标记为 required 来强制必须传入。

异步支持

Java 使用 Future/CompletableFuture 或库,无内置 async/await。

import java.util.concurrent.CompletableFuture;
public class Main {
    public static void main(String[] args) {
        CompletableFuture<String> future = fetchData();
        future.thenAccept(result -> System.out.println(result));
    }

    public static CompletableFuture<String> fetchData() {
        return CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(2000); // 模拟异步操作
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "Hello, Java!";
        });
    }
}

在 Dart 中,异步编程是语言的核心特性之一。Dart 使用 Futureasync/await 语法来处理异步操作。如下:

Future<void> main() async {
  var result = await fetchData();
  print(result);
}

Future<String> fetchData() async {
  return Future.delayed(Duration(seconds: 2), () => 'Hello, Dart!');
}

类和对象

Dart 的构造函数和 Java 类似,但 Dart 支持命名构造函数和可选参数。如下:

class Person {
  String name;
  int age;
  Person(this.name, this.age); // 简化的构造函数
  Person.named(this.name, {this.age = 18}); // 命名构造函数
}
void main() {
  var person1 = Person('Alice', 30);
  var person2 = Person.named('Bob', age: 25);
  print('${person1.name} is ${person1.age} years old.');
  print('${person2.name} is ${person2.age} years old.');
}

在 Java 中,类的定义和构造函数如下:

public class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }
}
public class Main {
    public static void main(String[] args) {
        Person person1 = new Person("Alice", 30);
        Person person2 = new Person("Bob", 25);
        System.out.println(person1.getName() + " is " + person1.getAge() + " years old.");
        System.out.println(person2.getName() + " is " + person2.getAge() + " years old.");
    }
}

Dart 支持工厂构造函数,可以根据条件返回不同的实例,在 Dart 中,factory 构造函数的作用是 控制类实例化过程,它可以决定是否创建新对象,或者返回一个已有的实例。这使得你可以实现 单例模式、缓存机制、延迟初始化 等更灵活的对象构建策略。例如:

class Person {
  String name;
  int age;
  Person._(this.name, this.age); // 私有构造函数
  factory Person(String name, int age) {
    if (age < 0) {
      age = 0;
    }
    return Person._(name, age);
  }
}
void main() {
  var person = Person('Alice', -5);
  print('${person.name} is ${person.age} years old.'); // 输出:Alice is 0 years old.
}

使用工厂实现单例模式:

class Singleton {
  static final Singleton _instance = Singleton._internal();
  factory Singleton() {
    return _instance;
  }
  Singleton._internal(); // 私有构造函数
  void doSomething() {
    print('Doing something...');
  }
}
void main() {
  var singleton1 = Singleton();
  var singleton2 = Singleton();
  print(singleton1 == singleton2); // 输出:true,两个实例是同一个
  singleton1.doSomething(); // 输出:Doing something...
}

Dart 支持 mixin,可以在类中混入其他类的功能:

mixin CanRun {
  void run() {
    print('Running...');
  }
}
class Animal {
  void eat() {
    print('Eating...');
  }
}
class Dog extends Animal with CanRun {
  void bark() {
    print('Barking...');
  }
}
void main() {
  var dog = Dog();
  dog.eat(); // 输出:Eating...
  dog.run(); // 输出:Running...
  dog.bark(); // 输出:Barking...
}

总结

Dart 和 Java 在语法和面向对象编程思想上有许多相似之处,但 Dart 提供了更灵活的类型推断、可选参数、内置异步支持(async/await)、工厂构造函数、mixin 混入等现代特性。Dart 的函数式编程能力和简洁的语法让开发效率更高,尤其适合快速开发跨平台应用(如 Flutter)。对于 Java 开发者来说,学习 Dart 可以帮助你拓展技术视野,掌握更现代的开发范式,并在移动和 Web 领域获得更多机会。希望本文能帮助你高效迁移到 Dart,并在实际项目中灵活运用这些新特性。