[英]Access a class's fields with Java reflection
I'm trying to access a document class that has id, name, text and list of words. 我正在尝试访问具有ID,名称,文本和单词列表的文档类。 I try to compare id which I have with the ids and when found get the list of words attached to this id to find exact word. 我尝试将我拥有的ID与ID进行比较,并在找到ID时附上单词列表以查找确切的单词。 I was trying with java reflection but I'm unable to get it working? 我尝试使用Java反射,但是无法正常工作?
Any help is highly appreciated. 非常感谢您的帮助。
public class Doc {
private static int documentID;
private static Doc docInstance = null;
private String documentText;
private ArrayList<String> listOfTokens;
static int docCount = 0;
public Doc() {
documentID = 0;
listOfTokens = new ArrayList<String>();
tokFreq = 0;
docCount++;
}
public static Doc getDocInstance() {
if (docInstance == null) {
docInstance = new Doc();
}
return docInstance;
}
public ArrayList<String> getListOfTokens() {
return listOfTokens;
}
}
and I am trying this 我正在尝试这个
public static void createDocumentVector(TreeMap<Integer,Integer>
documentVector, TreeMap<String, ArrayList<Integer>>qm, int N) throws
NoSuchFieldException, SecurityException, IllegalArgumentException,
IllegalAccessException, InstantiationException, NoSuchMethodException,
InvocationTargetException
{
int eachDoc = 0;
Collection<String> allKeys = qm.keySet();
ArrayList<Integer> l1 = new ArrayList<Integer>();
boolean addedTerm = false;
/**
Obtain an Iterator for Collection
*/
Iterator<String> itr = allKeys.iterator();
String key;
int termFrequency = 0;
int documentFrequency = 0;
/**
Iterate through TreeMap values iterator
*/
while(itr.hasNext())
{
key = (String)itr.next();
Integer LL = 0;
l1 = qm.get(key); // Returns value of that key
for (int k = 0; k < l1.size(); k++)
{
LL = l2.get(k);
Doc obj = new Doc();
Class<? extends Doc> docOb = obj.getClass();
Field field1 = docOb.getDeclaredField("documentID");
field1.setAccessible(true);
Field field2 = docOb.getDeclaredField("listOfTokens");
field1.setAccessible(true);
if (field1.isAccessible()) {
Method setID = docOb.getDeclaredMethod("setDocumentID", new Class[]{int.class});
setID.setAccessible(true);
setID.invoke(docOb, LL);
}
Method listTock = docOb.getMethod("getListOfTokens");
ArrayList<String> per = (ArrayList<String>) listTock.invoke(docOb, null);
for (String tock : per) {
if(tock.equals(key)) {
termFrequency++;
}
}
documentFrequency = l1.size();
eachDoc.add(getTFIDF(termFrequency, documentFrequency, N));
documentVector.put(eachDoc, LL);
addedTerm = true;
}
}
}
And I get this error 我得到这个错误
Exception in thread "main" java.lang.IllegalArgumentException: object is not an instance of declaring class
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
TreeMap<List<Integer>,Integer>
causes an error, due to this explanation in the javadoc . 由于javadoc中的此说明, TreeMap<List<Integer>,Integer>
导致错误。
The map is sorted according to the {@linkplain Comparable natural ordering} of its keys 映射根据其键的{@linkplain可比自然排序}进行排序
But List
does not implement the Comparable
interface. 但是List
没有实现Comparable
接口。 So you can't use List<Integer>
as a key in a TreeMap
. 因此,您不能将List<Integer>
用作TreeMap
的键。
My English is poor, hope you can understand! 我的英语很差,希望您能理解!
Did you post the complete definition of Doc
? 您是否发布了Doc
的完整定义? It's missing the setDocumentID
method. 它缺少setDocumentID
方法。
Anyway, I was able to reproduce your error with the following code: 无论如何,我能够使用以下代码重现您的错误:
public class DocReflection {
private static int documentId; // static field
private void setDocumentId(int docId) { // but setter is not static.
documentId = docId;
}
public static void main(String [] args) throws NoSuchFieldException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
DocReflection docReflection = new DocReflection();
Class<? extends DocReflection> cls = docReflection.getClass();
Field docId = cls.getDeclaredField("documentId");
docId.setAccessible(true);
if (docId.isAccessible()) {
Method setId = cls.getDeclaredMethod("setDocumentId", new Class[]{int.class});
setId.setAccessible(true);
setId.invoke(cls, 1); // <-- Invoking non-static method with class object.
}
}
}
Output: 输出:
Exception in thread "main" java.lang.IllegalArgumentException: object is not an instance of declaring class
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.company.DocReflection.main(DocReflection.java:28)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Solution is to make setDocumentId
static. 解决方案是使setDocumentId
静态。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.