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