Обходное решение для оберток Наборов Java, повреждающих отражение

Иногда другие библиотеки будут определять свой собственный size_t. Например, повышение. станд.:: size_t определяет определенное желание C++ стандартный.

size_t является типом стандарта C++, и он определяется в станд. пространства имен

5
задан Leo P 17 September 2009 в 01:02
поделиться

4 ответа

The reason for the exception being thrown is that the class obtained by the invocation

list.getClass()

in the line

System.out.println("size = " + list.getClass().getMethod("size").invoke(list));

returns the actual type - java.util.Collections$SynchronizedCollection. The SynchronizedCollection class happens to be an inner class of the Collections class, which you cannot access, hence the exception.

The best way to bypass this exception is to invoke the size method on a more suitable class/interface - usually this happens to be the implementation class (since that would definitely contain the method declaration or definition), but in our case we need to invoke size() on a public type given that obj.getClass() has returned a non-public type. To be specific, we need to invoke size() on the java.util.Collection (super)interface or the java.util.List interface.

The following statements will print out "size = 1" in the console:

System.out.println("size = " + Collection.class.getMethod("size").invoke(list));
System.out.println("size = " + List.class.getMethod("size").invoke(list));

Update

In case you were wondering whether the size() method invoked via reflection is synchronized or not, the answer is yes, it is synchronized. Despite invoking the size() method on the super type - Collection/List, the size() method in the SynchronizedCollection inner class gets invoked, and this happens to be synchronized. This is an implementation detail though, guaranteed to work since the collection is wrapped.

Besides, it it not a good idea to use reflection when the supertype - the Collection interface contains the size() method.

5
ответ дан 14 December 2019 в 01:12
поделиться

Получить метод из Collection.class (в более общем случае перебирайте суперклассы (и интерфейсы), чтобы найти что-то общедоступное). Или просто не используйте отражение.

3
ответ дан 14 December 2019 в 01:12
поделиться

java.util.Collections$SynchronizedCollection is non-public class.

1
ответ дан 14 December 2019 в 01:12
поделиться

Are you sure the java.util.concurrent choices would be slower (or, slower enough to worry about?).

I guess your 2 choices there are:

  1. LinkedBlockingQueue
  2. CopyOnWriteArrayList

I think for certain use cases, these implementations may actually be faster. And as a side note, if you eventually need it, the collections in java.util.concurrent can handle concurrent modification.

From the Concurrent Collections section of "Java Concurrency In Practice":

CopyOnWriteArrayList is a concurrent replacement for a synchronized List that offers better concurrency in some common situations and eliminates the need to lock or copy the collection during iteration. (Similarly, CopyOnWriteArraySet is a concurrent replacement for a synchronized Set.)

0
ответ дан 14 December 2019 в 01:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: