Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Returns data type name (string) for getTypeStr() in FieldInfo class #140

Closed
febielgiva opened this issue Sep 21, 2017 · 11 comments
Closed

Comments

@febielgiva
Copy link

febielgiva commented Sep 21, 2017

for a object of FieldInfo the getTypeStr() return the field's data type example "Integer/String/int" but I need to check whether the data type is valid or not .

I need to pass the data type's class to the below function
public static boolean isValidType(Class<?> retType) { if (retType.isPrimitive() && retType != void.class) return true; if (Number.class.isAssignableFrom(retType)) return true; if (AbstractCode.class.isAssignableFrom(retType)) return true; if (Boolean.class == retType) return true; if (Character.class == retType) return true; if (String.class == retType) return true; if (Date.class.isAssignableFrom(retType)) return true; if (byte[].class.isAssignableFrom(retType)) return true; if (Enum.class.isAssignableFrom(retType)) return true; return false; }

But what i have is data type name ( string) which is useless . You should store the class type of the data type like the REFLECT Field variables.

@febielgiva febielgiva changed the title Returns string for fieldType Returns data type name (string) for getTypeStr() in FieldInfo class Sep 21, 2017
@lukehutch
Copy link
Member

Field has methods getType() (which is easy to support, I can add that) and getGenericType() (which is not easy to support, the subclasses of Type do not have public constructors).

However, just adding getType() is incomplete. It also can trigger arbitrary class initializer blocks to run, because it requires the ClassLoader to load classes for some types. (This can probably even lead to MadGadget-like security vulnerabilities in some cases.) Therefore, it's not ideal for classpath scanning. But I guess if I write a big caveat about it in the documentation, maybe people can decide to take this risk for themselves!

lukehutch added a commit that referenced this issue Sep 22, 2017
@lukehutch
Copy link
Member

Oh, it gets worse than that: If the type of the field is say String[], then field.getType() returns Class<String[]>, which it is not possible to construct. So even getType() will be broken some of the time.

What you probably need to do is just load the class whose fields you want to probe, and then use regular reflection to test if the fields have the properties you want. The correct way to load classes given a ScanResult is ScanResult#classNamesToClassRefs(List<String> classNames) or ScanResult#classNameToClassRef(String className).

Does that work for you?

@febielgiva
Copy link
Author

okay . Got it will try it out. I am working on speed test to compare between reflection and your library for a project in my company. If your lib is efficient we would migrate to it. So please do consider this as request and implement these in future. Thank you .

@lukehutch
Copy link
Member

@febielgiva based on a great suggestion by @Alexander--, the exact method you were looking for is now supported: FieldInfo#getType(). (A similar method exists for methods and annotations on fields or methods.) Can you please test the github master version?

@lukehutch lukehutch reopened this Sep 23, 2017
@lukehutch
Copy link
Member

@febielgiva Added a unit test that seems to indicate this should be working for you too now, so I'll close this. Please still comment if you do test this, to let me know how it goes for you. I'll also release a new version now. Thanks for this report!

lukehutch added a commit that referenced this issue Sep 23, 2017
@lukehutch
Copy link
Member

PS please also let me know what your benchmark scores were for the two libraries, I'm interested in real-world numbers. Thanks.

@febielgiva
Copy link
Author

sure I will let know once I tested it . Thank you for implementing those. its would be really useful. Do you have any method similar to invoke() method in reflect and a method to get just the constructor of a class? .

Thank you .

@lukehutch
Copy link
Member

You can't invoke a method in this way, because the class hasn't even been loaded (assuming other code hasn't already loaded the calss) -- that's the whole point of ClassInfo, to store info about the class that is read from the classfile directly, without calling the classloader.

The constructors are called <init> in the classfile binary (there is also <clinit> for the static class initializer). But I rename <init> to the name of the class, since the name of the class is the name of the constructor in Java source. So you can just search for the name of the class among the MethodInfo methods to get the constructors. However, I just realized I am using fully-qualified classnames, rather than just the class' "simple name" (leaf name), so the constructor for String will be java.lang.String (which is not correct or helpful). So -- either I should switch this to use just the simple name (String etc.), or maybe I should switch the constructors back to use <init>, since there are still <clinit> blocks anyway, and those don't have a name in Java source. What is your preference?

@lukehutch lukehutch reopened this Sep 26, 2017
@lukehutch
Copy link
Member

I went ahead and made these changes:

  • Constructors are now named <init>.
  • I added ClassInfo#getConstructors() and ClassInfo#getMethodsAndConstructors().
  • ClassInfo#getMethods() now does not return constructors, to work similarly to java.lang.reflect.

@lukehutch
Copy link
Member

(PS although I closed this, I'm still interested in benchmarks, whenever you have a chance to report on that -- no rush, and thanks!)

@lukehutch
Copy link
Member

Released in 2.7.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants