I am trying to get an instance of a non-visible class, AKA package private class, using reflection. I was wondering if there was a way to switch the modifiers to make it public and then access it using Class.forName
. When I try that now it stops me saying I can't do it. Unfortunately there is no setAccesible
method of the Class
class.
相关问题
- Delete Messages from a Topic in Apache Kafka
- Jackson Deserialization not calling deserialize on
- How to maintain order of key-value in DataFrame sa
- StackExchange API - Deserialize Date in JSON Respo
- Difference between Types.INTEGER and Types.NULL in
You can use Manifold's @Jailbreak for direct, type-safe Java reflection:
Here
@Jailbreak
enables the compiler to resolve the constructor type-safely as if public, while Manifold generates efficient reflection code for you under the hood.Additionally you can use
@Jailbreak
to access and construct non-visible classes:For hidden class access, Java's annotation grammar requires the class to be annotated apart from its package.
More generally you can use
@Jailbreak
for any type of reflection:@Jailbreak
unlocks the foo local variable in the compiler for direct access to all the members inFoo
's hierarchy.Similarly you can use the jailbreak() extension method for one-off use:
Through the
jailbreak()
method you can access any member inFoo
's hierarchy.Discover more about Manifold.
Class.forName
should work. If the class is within a package hierarchy list in the"package.access"
security property, then you will need to perform the operation with the appropriate privilege (usually all permissions; or don't have a security manager).If you are trying to use
Class.newInstance
, don't.Class.newInstance
handles exceptions poorly. Instead get aConstructor
and callnewInstance
on that. It's difficult to see what you are having problems with without the exception trace.As ever, most but not all uses of reflection are bad ideas.
We recently released a library that helps a lot to access private fields, methods and inner classes through reflection : BoundBox
For a class like
It provides a syntax like :
The only thing you have to do to create the BoundBox class is to write
@BoundBox(boundClass=Outer.class)
and theBoundBoxOfOuter
class will be instantly generated.I had requirement to copy the value of field from older version of object if the value is null in latest version. We had these 2 options.
Core Java :
Using Spring [org.springframework.beans.BeanWrapper] :
nested class - class defined within other class (includes static and non-static classes)
inner class - non-static nested class (instance of inner class need instance of outer class to exist)
non-nested (top level) classes
Based on your question we know that constructor you want to access is not public. So your class may look like this (
A
class is in some package different than ours)To create instance of this class we need to get to constructor we want to invoke, and make it accessible. When it is done we can use
Constructor#newInstance(arguments)
to create instance.nested and inner classes
If you want to access nested (static and non-static) Class with
Class.forName
you need to use syntax:Outer$Nested
says thatNested
class is declared withinOuter
class. Nested classes are very similar to methods, they have access to all members of its outer class (including private ones).But we need to remember that instance of inner class to exists requires instance of its outer class. Normally we create them via:
so as you see each instance of Inner class have some information about its outer class (reference to that outer instance is stored in
this$0
field, more info: What does it mean if a variable has the name "this$0" in IntelliJ IDEA while debugging Java?)So while creating instance of
Inner
class withConstructor#newInstance()
you need to pass as first argument reference to instance ofOuter
class (to simulateouter.new Inner()
behavior).Here is an example.
in package1
in package2
static-nested classes
Instances of static-nested classes don't require instance of Outer class (since they are static). So in their case we don't need to look for constructor with
Outer.class
as first argument. And we don't need to pass instance of outer class as first argument. In other words code will be same as for non-nested (top-level) class (maybe except fact that you would need to add$Nested
syntax inClass.forName()
).