blob: 18a2096444c37e53e1f37fd8cc85d839fd6f5e11 [file] [edit]
// Copyright (c) 2026, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// dart format width=74
// ignore_for_file: avoid_dynamic_calls, avoid_print
// ignore_for_file: non_constant_identifier_names, omit_local_variable_types
// ignore_for_file: unused_local_variable
import 'package:jni/jni.dart';
dynamic JList;
class Foo {
Bar? bar;
JString someJString() => throw UnimplementedError();
JObject someJNumber() => throw UnimplementedError();
void release() {}
}
class Bar {
Bar._();
factory Bar.implement($Bar impl) => Bar._();
}
abstract base mixin class $Bar {
factory $Bar({required Foo Function() f}) = _BarImpl;
Foo f();
}
final class _BarImpl with $Bar {
final Foo Function() _f;
_BarImpl({required Foo Function() f}) : _f = f;
@override
Foo f() => _f();
}
void releaseManualExample() {
// snippet-start#release_manual
// Construct the object.
final hello = 'Hello'.toJString();
// Use it.
print(hello);
// Eagerly release it!
hello.release();
// snippet-end#release_manual
}
void arenaUsingExample() {
// snippet-start#arena_using
using((arena) {
final hello = 'Hello'.toJString()..releasedBy(arena);
final world = 'World'.toJString()..releasedBy(arena);
print(hello);
print(world);
});
// Both `hello` and `world` are now released.
// snippet-end#arena_using
}
void javaCollectionsExample() {
// snippet-start#java_collections
// GOOD:
final jstrings = JList(JString.type);
using((arena) {
final hello = 'Hello'.toJString()..releasedBy(arena);
final world = 'World'.toJString()..releasedBy(arena);
jstrings.add(hello); // Add to Java collection
jstrings.add(world); // Add to Java collection
});
print(jstrings.length); // prints 2.
// snippet-end#java_collections
}
void releaseOriginalExample() {
// snippet-start#release_original
final foo = Foo();
final String string = foo.someJString().toDartString(releaseOriginal: true);
final JInteger jint =
foo.someJNumber().as(JInteger.type, releaseOriginal: true);
final int dartInt = jint.toDartInt(releaseOriginal: true);
foo.release();
// All references are removed.
// snippet-end#release_original
}
void cycleExample() {
// snippet-start#cycle
final foo = Foo();
foo.bar = Bar.implement($Bar(
f: () {
return foo;
},
));
// snippet-end#cycle
}
void cycleBreakerExample() {
final foo = Foo();
// snippet-start#cycle_breaker
final weakFoo = WeakReference(foo);
foo.bar = Bar.implement($Bar(
f: () {
final foo = weakFoo.target;
if (foo == null) {
throw StateError('Foo was collected');
}
return foo;
},
));
// snippet-end#cycle_breaker
}
// snippet-start#cycle_breaker_class
final class BarImpl with $Bar {
final WeakReference<Foo> weakFoo;
BarImpl(this.weakFoo);
@override
Foo f() {
final foo = weakFoo.target;
if (foo == null) {
throw StateError('Foo was collected');
}
return foo;
}
}
void cycleBreakerClassMain(Foo foo) {
final weakFoo = WeakReference(foo);
foo.bar = Bar.implement(BarImpl(weakFoo));
// ...
}
// snippet-end#cycle_breaker_class