In libusb, the bus structure (with devices, configurations, interfaces and endpoints) is represented in C struct's. These structures are kept there, no Java object are created out of them. In the C/C++ wrapper we keep the native (libusb) device pointers. Every call from Java is initiated over this device pointer. So we can be sure to access at any time most actual USB information the libusb has.
In Java you can access the descriptors with a tree-like object structure and you don't have to worry about the internal pointers and struct's. This tree-like object structure provides a simple device class which represents an USB device and makes it easy to write to and read from it. Errors and timeouts will result in exceptions.