Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qjniarray.qdoc
Go to the documentation of this file.
1// Copyright (C) 2024 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
3
4/*!
5 \class QJniArrayBase
6 \brief The QJniArrayBase class provides common, type-independent APIs for QJniArray.
7 \inmodule QtCore
8 \ingroup frameworks-technologies
9 \since 6.8
10*/
11
12/*!
13 \typedef QJniArrayBase::size_type
14
15 A 32 bit integer.
16*/
17
18/*!
19 \fn template <typename Container, QJniArrayBase::if_compatible_source_container<Container>> auto QJniArrayBase::fromContainer(Container &&container)
20
21 Creates a Java array holding the data in \a container, and returns a
22 QJniArray instance that wraps it.
23
24//! [forward-iterable-containers]
25 \constraints \c{Container}
26 is a container that stores elements of a \l{JNI types}{JNI type} or equivalent
27 C++ type, and provides a forward iterator.
28
29 The specialization of the constructed QJniArray depends on the value type
30 of the \a container. For a \c{Container<T>} (such as e.g. \c{QList<T>}) it
31 will typically be \c{QJniArray<T>}, with the following exceptions:
32
33 \table
34 \header
35 \li Container
36 \li Specialization
37 \row
38 \li QByteArray
39 \li QJniArray<jbyte>
40 \row
41 \li QStringList
42 \li QJniArray<jstring>
43 \header
44 \li Container::value_type
45 \li Specialization
46 \row
47 \li QJniObject
48 \li QJniArray<jobject>
49 \endtable
50//! [forward-iterable-containers]
51
52 \sa QJniArray::toContainer()
53*/
54
55/*!
56 \fn QJniArrayBase::operator QJniObject() const
57
58 \return a QJniObject wrapping the same \c{jobject} as this QJniArray instance.
59*/
60
61/*!
62 \fn void QJniArrayBase::swap(QJniArrayBase &other)
63 \memberswap{array object}
64*/
65
66/*!
67 \fn template <typename T> T QJniArrayBase::object() const
68
69 \return the object held by the QJniArray as type T, which can be one of the
70 \l {QJniObject#Object Types}{JNI Object Types}.
71*/
72
73/*!
74 \fn bool QJniArrayBase::isValid() const
75
76 \return whether the QJniArray object wraps a valid `jobject`. For invalid
77 QJniArray instances, object() returns \nullptr. Iterating over an invalid
78 object is safe (begin() will return the same as end()), and calling
79 \l{QJniArray::}{toContainer()} on an invalid array will return an empty
80 container.
81
82 \sa QJniObject::isValid(), object(), QJniArray::toContainer()
83*/
84
85/*!
86 \fn bool QJniArrayBase::isEmpty() const
87
88 \return \c true if the array has size 0; otherwise returns \c false.
89
90 An \l{isValid}{invalid} array is always empty.
91
92 \c isValid(), size()
93*/
94
95/*!
96 \fn QJniArrayBase::size_type QJniArrayBase::size() const
97
98 \return the size of the array.
99*/
100
101/*!
102 \class QJniArray
103 \brief The QJniArray class is a template class that represents an array in Java.
104 \inmodule QtCore
105 \ingroup frameworks-technologies
106 \since 6.8
107
108 The QJniArray template makes it easy to work with Java methods that return
109 or take a Java array.
110
111 \note \l{Java arrays} can hold primitive types and objects. The array
112 itself can be treated like a Java Object, and the JNI framework provides
113 explicit APIs to work with such arrays. In addition, the Java class library
114 provides container types such as \c{List} or \c{ArrayList}. Objects of
115 those types can not be represented by a QJniArray. Instead, use QJniObject
116 to call the class-specific member functions.
117
118 To create a QJniArray instance, either construct it from a corresponding C++
119 container:
120
121 \code
122 QList<int> intList;
123 const QJniArray intArray = QJniArray(intList);
124 \endcode
125
126 or from an initializer list:
127
128 \code
129 const QJniArray intArray{1, 2, 3};
130 \endcode
131
132 QJniArray will create a new Java array and copy the C++-side data into it.
133
134 When calling functions that return an array via QJniObject::callMethod,
135 such as \c{char[] toCharArray()} in the Java \c{String} class, specify the
136 return type as a C array (\c{jchar[]} in the following):
137
138 \code
139 const auto charArray = stringObject.callMethod<jchar[]>("toCharArray");
140 \endcode
141
142 The \c{charArray} variable will be of type \c{QJniArray<jchar>}, and hold
143 a new global reference to the \c{jcharArray} JNI object.
144
145 Note that the arrays in the code snippets above are all const. Accessing
146 elements in a const array is considerably more efficient than operating on
147 a mutable array.
148
149 A QJniArray can also be constructed from an existing \c{jarray} or
150 QJniObject. However, note that no type checking is performed to verify that
151 the \c{jarray} or QJniObject indeed represents an array holding elements of
152 the specified type, and accessing a mismatching QJniArray results in
153 undefined behavior.
154
155 The data in a QJniArray can either be accessed element by element using
156 at() or \l{QJniArray::}{operator[]()}, or iterated over.
157
158 \code
159 for (const auto &value : array)
160 process(value);
161 \endcode
162
163 To copy the entire array into a C++ side Qt container, use the toContainer()
164 function.
165
166 \code
167 const auto bytes = object.callMethod<jbyte[]>("getBytes");
168 QByteArray data = bytes.toContainer();
169 \endcode
170
171 which happens implicitly in
172
173 \code
174 const auto data = object.callMethod<QByteArray>("getBytes");
175 \endcode
176
177 The return type of toContainer() depends on the type that QJniArray has
178 been instantiated with.
179//! [type-mapping]
180 For \c{QJniArray<T>} this will typically be \c{QList<T>}, with the
181 following exceptions:
182
183 \table
184 \header
185 \li Specialization
186 \li C++ type
187 \row
188 \li QJniArray<jbyte>
189 \li QByteArray
190 \row
191 \li QJniArray<char>
192 \li QByteArray
193 \row
194 \li QJniArray<jstring>
195 \li QStringList
196 \row
197 \li QJniArray<QString>
198 \li QStringList
199 \endtable
200//! [type-mapping]
201
202 An array of a fixed size can also be created without any data, and can then
203 be populated element by element using
204 \l{QJniArray::operator[]()}{operator[]}:
205
206 \code
207 QJniArray<jint> intArray(size);
208 for (int i = 0; i < size; ++i)
209 intArray[i] = i;
210 \endcode
211
212 or a mutable iterator:
213
214 \code
215 QJniArray<QString> strings(size);
216 int i = 0;
217 for (auto string : strings) // note: not 'auto &string'
218 string = u"Row %1"_s.arg(i++);
219 \endcode
220
221 As in Java, the size of an array can not be changed, but the array variable
222 can be assigned to a different array.
223
224 \note Java arrays are limited to 32 bits, and the \c{size_type} member type of
225 QJniArray is \c{jsize}, which is a 32bit integer type. Trying to construct
226 a QJniArray from a C++ container that holds more than 2^32 elements will
227 cause a runtime assertion.
228*/
229
230/*!
231 \fn template <typename T> QJniArray<T>::QJniArray()
232
233 Default constructor of QJniArray. This does not create a Java-side array,
234 and the instance will be invalid.
235
236 \sa isValid
237*/
238
239/*!
240 \fn template <typename T> QJniArray<T>::QJniArray(jarray array)
241
242 Constructs a QJniArray that wraps the Java-side array \a array,
243 creating a new global reference to \a array.
244
245//! [no-array-validation]
246 \note This constructor does not perform any validation of whether the
247 Java-side object is an array of the correct type. Accessing a
248 mismatching QJniArray results in undefined behavior.
249//! [no-array-validation]
250*/
251
252/*!
253 \fn template <typename T> QJniArray<T>::QJniArray(const QJniObject &object)
254
255 Constructs a QJniArray that wraps the same Java array as \a object,
256 creating a new global reference. To construct a QJniArray from an existing
257 local reference, use a QJniObject constructed via
258 \l{QJniObject::}{fromLocalRef()}.
259
260 \include qjniarray.qdoc no-array-validation
261*/
262
263/*!
264 \fn template <typename T> QJniArray<T>::QJniArray(QJniObject &&object)
265
266 Constructs a QJniArray by moving from \a object. The QJniObject becomes
267 \l{QJniObject::isValid}{invalid}.
268
269 \include qjniarray.qdoc no-array-validation
270*/
271
272/*!
273 \fn template <typename T> template <typename Other, QJniArrayBase::if_convertible<Other, T>> QJniArray<T>::QJniArray(const QJniArray<Other> &other)
274
275 Constructs a QJniArray by copying \a other. Both QJniArray objects will
276 reference the same Java array object.
277
278 \constraints the element
279 type \c{Other} of \a other is convertible to the element type \c{T} of the
280 QJniArray being constructed. However, no actual conversion takes place.
281*/
282
283/*!
284 \fn template <typename T> template <typename Other, QJniArrayBase::if_convertible<Other, T>> QJniArray<T>::QJniArray(QJniArray<Other> &&other)
285
286 Constructs a QJniArray by moving from \a other. The \a other array becomes
287 \l{QJniArrayBase::isValid}{invalid}.
288
289 \constraints the element
290 type \c{Other} of \a other is convertible to the element type \c{T} of the
291 QJniArray being constructed. However, no actual conversion takes place.
292*/
293
294/*!
295 \fn template <typename T> template <typename Other, QJniArrayBase::if_convertible<Other, T>> QJniArray &QJniArray<T>::operator=(const QJniArray<Other> &other)
296
297 Assigns \a other to this QJniArray, and returns a reference to this. Both
298 QJniArray objects will reference the same Java array object.
299
300 \constraints the element
301 type \c{Other} of \a other is convertible to the element type \c{T} of this
302 QJniArray. However, no actual conversion takes place.
303*/
304
305/*!
306 \fn template <typename T> template <typename Other, QJniArrayBase::if_convertible<Other, T>> QJniArray &QJniArray<T>::operator=(QJniArray<Other> &&other)
307
308 Moves \a other into this QJniArray, and returns a reference to this. The
309 \a other array becomes \l{QJniArrayBase::isValid}{invalid}.
310
311 \constraints the element
312 type \c{Other} of \a other is convertible to the element type \c{T} of this
313 QJniArray. However, no actual conversion takes place.
314*/
315
316/*!
317 \fn template <typename T> template <typename Container, QJniArrayBase::if_compatible_source_container<Container>> QJniArray<T>::QJniArray(Container &&container)
318
319 Constructs a QJniArray that wraps a newly-created Java array for elements of
320 type \c{Container::value_type}, and populates the Java array with the data from
321 \a container.
322
323 \include qjniarray.qdoc forward-iterable-containers
324
325 \sa QJniArrayBase::fromContainer(), toContainer()
326*/
327
328/*!
329 \fn template <typename T> QJniArray<T>::QJniArray(std::initializer_list<T> &list)
330
331 Constructs a QJniArray that wraps a newly-created Java array for elements of
332 type \c{T}, and populates the Java array with the data from \a list.
333
334 \sa QJniArrayBase::fromContainer(), toContainer()
335*/
336
337/*!
338 \fn template <typename T> QJniArray<T>::QJniArray(size_type size)
339 \since 6.9
340
341 Constructs an empty QJniArray of size \a size. The elements in the array do
342 not get initialized.
343*/
344
345/*!
346 \fn template <typename T> QJniArray<T>::~QJniArray()
347
348 Destroys the QJniArray object and releases any references held to the
349 wrapped Java array.
350*/
351
352/*!
353 \fn template <typename T> auto QJniArray<T>::arrayObject() const
354
355 \return the wrapped Java object as the suitable \c{jarray} type that
356 matches the element type \c{T} of this QJniArray object.
357
358 \table
359 \header
360 \li T
361 \li jarray type
362 \row
363 \li jbyte
364 \li jbyteArray
365 \row
366 \li jchar
367 \li jcharArray
368 \row
369 \li ...
370 \li ...
371 \row
372 \li jobject
373 \li jobjectArray
374 \row
375 \li QJniObject
376 \li jobjectArray
377 \row
378 \li Q_DECLARE_JNI_CLASS
379 \li jobjectArray
380 \endtable
381*/
382
383/*!
384 \typedef QJniArray::const_iterator
385
386 A random-access, const iterator for QJniArray.
387*/
388
389/*!
390 \typedef QJniArray::const_reverse_iterator
391
392 A reverse iterator for the QJniArray, synonym for
393 \c{std::reverse_iterator<const_iterator>}.
394*/
395
396/*!
397 \fn template <typename T> const_iterator QJniArray<T>::begin() const
398 \fn template <typename T> iterator QJniArray<T>::begin()
399 \fn template <typename T> const_iterator QJniArray<T>::constBegin() const
400 \fn template <typename T> const_iterator QJniArray<T>::cbegin() const
401
402 Returns an \l{STL-style iterators}{STL-style const iterator} pointing to the
403 first item in the array.
404
405 If the array is \l{QJniArrayBase::isValid()}{invalid}, then this will return
406 the same iterator as the corresponding end() function.
407
408 \sa end(), rbegin()
409*/
410
411/*!
412 \fn template <typename T> const_iterator QJniArray<T>::end() const
413 \fn template <typename T> iterator QJniArray<T>::end()
414 \fn template <typename T> const_iterator QJniArray<T>::constEnd() const
415 \fn template <typename T> const_iterator QJniArray<T>::cend() const
416
417 Returns an \l{STL-style iterators}{STL-style iterator} pointing just
418 after the last item in the list.
419
420 \sa begin(), rend()
421*/
422
423/*!
424 \fn template <typename T> const_reverse_iterator QJniArray<T>::rbegin() const
425 \fn template <typename T> reverse_iterator QJniArray<T>::rbegin()
426 \fn template <typename T> const_reverse_iterator QJniArray<T>::crbegin() const
427
428 Returns an \l{STL-style iterators}{STL-style reverse iterator} pointing to
429 the first item in the array, in reverse order.
430
431 If the array is \l{QJniArrayBase::isValid()}{invalid}, then this will return
432 the same iterator as the corresponding rend() function.
433
434 \sa rend(), begin()
435*/
436
437/*!
438 \fn template <typename T> const_reverse_iterator QJniArray<T>::rend() const
439 \fn template <typename T> reverse_iterator QJniArray<T>::rend()
440 \fn template <typename T> const_reverse_iterator QJniArray<T>::crend() const
441
442 Returns an \l{STL-style iterators}{STL-style reverse iterator} pointing just
443 after the last item in the list, in reverse order.
444
445 \sa rbegin(), end()
446*/
447
448/*!
449 \fn template <typename T> T QJniArray<T>::operator[](size_type i) const
450 \fn template <typename T> T QJniArray<T>::at(size_type i) const
451
452 Returns the value at position \a i in the wrapped Java array.
453
454 \a i must be a valid index position in the list (i.e.,
455 0 <= \a i < size()).
456
457 \sa size()
458*/
459
460/*!
461 \fn template <typename T> QJniArray<T>::reference QJniArray<T>::operator[](size_type i)
462 \since 6.9
463
464 Returns a reference object for value at position \a i in the wrapped Java
465 array.
466
467 \a i must be a valid index position in the list (i.e., 0 <= \a i < size()).
468
469 The returned reference object holds the value at position \a i, and in most
470 cases will convert implicitly to the value. Assigning to the returned
471 reference will overwrite the entry in the Java array. However, calling
472 mutating member functions on the object will not modify the entry in the
473 array. To call member function on the result of this operator, dereference
474 the reference object:
475
476 \code
477 QJniArray<QString> strings = object.callMethod<QString[]>("getStrings");
478 if (!strings.isEmpty()) {
479 if (!(*array[0]).isEmpty()) {
480 // ...
481 }
482 }
483 \endcode
484
485 However, if modifying the value in the array itself is not intended, make
486 the array const, or use \l{at()} instead.
487
488 \sa at(), size()
489*/
490
491/*!
492 \fn template <typename T> template <typename Container, QJniArrayBase::if_compatible_target_container<T, Container>> Container QJniArray<T>::toContainer(Container &&container) const
493
494 \return a container populated with the data in the wrapped Java array.
495
496 If no \a container is provided, then the type of the container returned
497 depends on the element type of this QJniArray.
498 \include qjniarray.qdoc type-mapping
499
500 If you pass in a named container (an lvalue) for \a container, then that
501 container is filled, and a reference to it is returned. If you pass in a
502 temporary container (an rvalue, incl. the default argument), then that
503 container is filled, and returned by value.
504
505 This function returns immediately if the array is
506 \l{QJniArrayBase::isValid()}{invalid}.
507
508 \sa QJniArrayBase::fromContainer()
509*/