Find private inner class using reflection - java

In the context of android.accounts.AccountManager:
public class AccountManager {
private abstract class AmsTask extends FutureTask<Bundle> implements AccountManagerFuture<Bundle> {
...
}
}
I would like to find the inner class by name using reflection, as I require a Class object to determine staticness of member methods. In the simple case
public class AccountManager {
public class Foo {
...
}
}
This can be done using Class.forName("android.accounts.AccountManager$Foo"). However, the private modifier eliminates this possibility. I tried searching through Class.forName("android.accounts.AccountManager").getDeclaredClasses(), but it returns an empty list. Its specification covers private member classes, so I am at a loss why it is not returned by the getter. I presume it has something to do with abstract.
EDIT: Experiments have shown getDeclaredClasses() to work with the following snippet, but not with the actual Android class.
public class Test {
private abstract class AmsTask extends LinkedList implements TestInterface {
...
}
private interface TestInterface{}
}
The suggestion that using AccountManager's class loader might help, did not turn out to be fruitful.
Class am = Class.forName("android.accounts.AccountManager");
Class.forName("android.accounts.AccountManager$AmsTask",false,am);
resulted in a ClassNotFoundException during the latter call.

Related

Extending a generic class into a static inner class

I am having issues extending an inner class with a generic abstract class.
I get an Non-static field cannot be referenced from a static context which is odd because the class itself is static, not necessarily the field value.
This is basically what I have:
// AbstractFoo.java
public abstract class AbstractFoo extends FrameLayout {
// Some logic
}
// AbstractBar.java
public abstract class AbstractBar<T> {
int someNumber;
// Some logic
}
// Foo.java
public class Foo extends AbstractFoo {
// Some logic
// Foo.InnerFoo.java
public static class InnerFoo extends AbstractBar<InnerFoo> {
public InnerFoo() {
super.someNumber = 5; // Compiler error HERE
}
}
}
For some reason I cannot access someNumber from InnerFoo. From my understanding this shouldn't cause any issues. The classes I'm extending btw is from an external library.
This is also all done with Android where minimum SDK is 24.
Thanks for the help!
The fields defined in your classes do not have an explicit access modifier which would use the default access modifier and limit the visibility to classes within the same package.
You should make the fields in AbstractBar as protected -
public abstract class AbstractBar<T> {
protected int someNumber;
}

how to access abstract class inside an interface

this is more of a java question rather than an android question. If we look at the code below, I need to access getEnrollmentUsername from my main class:
public interface IAirWatchSDKService extends android.os.IInterface {
public String getEnrollmentUsername(String publicKey);
public abstract static class Stub extends Binder implements IAirWatchSDKService {
private static class Proxy implements IAirWatchSDKService {
#Override
public IBinder asBinder() {
return null;
}
public String getEnrollmentUsername(String publicKey){
return "it worked";
}
}
}
}
but the problem is that it is wrapped inside of an abstract class. How can I get to it from my main class? And none of this code can change because it is part of a library, rather I need to write code from my main class only.
Proxy is declared as a private class. To access it from outside it needs public, protected or default(package private) depending on where you want to access it from.
Best practice is that if your main class needs to run this method, it should implement the interface. That, or the main class is aware of the interface with a method such as this: myIAirWatchSDKService.getEnrollmentUsername(s)

What is the best practice in Java to set a constant required in subclasses?

I have the following situation:
A parent class has a function that depends on a constant. But the only valid place to define that constant is in subclasses (parent class cannot define the constant's value, but it can be used with the constant undefined in 99% of use cases - the constant is a default to use if a specific configuration element is missing).
However, I would like to enforce that any child class inheriting from that parent class must define the value for the constant, since any child classes have to be able to use the other 1% of functionality.
What is the best practice to implement this enforcement in Java, ideally at compile time? (clearly, at runtime, I can simply check if the constant is null/empty in the method using it).
My own solution was to implement a value-getter for the constant as an abstract method in the parent class, and call that in combination with the real setter in the constructor; something like this:
public class HelperClass1 {
private String myConstant;
public void setMyConstant() {} // implemented obviousy
public void myMethod() { // Called from ParentClass's methods
// Do something useful with myConstant
}
}
import HelperClass1;
public abstract class ParentClass {
ParentClass() {
HelperClass1.setMyConstant( getMyConstantValue() );
}
public abstract void getMyConstantValue();
}
public class ChildClass1 extends ParentClass {
public void getMyConstantValue() { return "BUZZ"; }
}
public class ChildClass2 extends ParentClass {
} // Fails to compile without getMyConstantValue()
However, (a) This implementation has a problem (I can't use ParentClass itself, since it's now abstract) without subclassing; and (b) since I'm not a Java developer, I'm afraid that this isn't the best or the most elegant solution. So I'd like to know if there's a best practices approach that improves on what I implemented.
Provide two constructors for the parent class:
One is a protected constructor which takes the constant as an argument.
The other is private constructor which can construct instances of the parent class without setting the constant.
Provide a factory method for the parent class which can call the private no-constant constructor.
Classes that want to get an instance of the parent class can call the factory method. But child classes that want to inherit from the parent class have to call the protected constructer, which can validate that a valid constant was passed.
public class ParentClass {
private final SomeClass myConstant;
protected ParentClass(SomeClass aConstant) {
if (null == aConstant) {
throw new IllegalArgumentException("...");
}
myConstant = aConstant;
}
private ParentClass() {
myConstant = null;
}
public static ParentClass getInstance() {
return new ParentClass();
}
}
public class ChildClass {
public ChildClass() {
super(new SomeClass(42));
}
}
This isn't perfect. Someone could write a child class that passes a bad constant to the superclass constructor, and it wouldn't actually fail until some code tried to construct an instance of the child class.

How to design a common static method in all classes implementing an interface

I have an interface called Relation, implemented by a class BasicRelation, and extended by subclasses (e.g. ParentChild, Sibling, Spouse). While developing my code, I realized that I often need a method which takes a String representation of a relation to create it. For example:
public class ParentChild implements Relation extends BasicRelation {
// e.g. "Jack is Emily's father. Jill is her mother." will return the list
// <ParentChild(Jack, Emily), ParentChild(Jill, Emily)>
static List<ParentChild> fromSentence(String s) {
...
}
}
Now, since I find myself needing this method (fromSentence(String)) in every class, except perhaps in BasicRelation, I would like to move it up the hierarchy. The problem is that the internal details of the method is subclass-dependent, so I can't have it as a static method in the interface Relation or the superclass BasicRelation.
Unfortunately, in Java, it is also not possible to have a static abstract method.
Is there any way to ensure that every subclass of BasicRelation (or every class implementing Relation) implements fromSentence(String)? If no, should I be designing this in a completely different way? I guess this last question is more of a request for design-advice than a question.
Why does the static method need to be in the interface? What's stopping you from having a 'Utility' class and having the method in there?
public class RelationUtility {
public static BasicRelation relationFactory(String asString) {
....
}
}
As a static method, there is no reason other than access to private members, which can also be accomplished by by 'default' permissions on those members....
You can try making the BasicRelation class an abstract class and use an abstract fromSentence(..) method. This would require the ParentChild class to override and implement the fromSentence method because you can't create an object for ParentChild without implementing fromSentence()
public abstract class BasicRelation extends Relation(){
public abstract List<..> fromSentence(String s);
}
public class ParentChild implements Relation extends BasicRelation {
fromSentence(){
//parentChild class's implementation
}
}
If I understood right... you can try an approach like this
public class BasicRelation {
public abstract List<ParentChild> fromSentenceInSubclass(s);
public List<ParentChild> fromSentence(String s){
fromSentenceInSubclass(s);
}
}
And then you could have:
public class SubclassRelation extends BasicRelation {
public List<ParentChild> fromSentenceInSubclass(s){
// do subclass relation stuff
}
}
You will probably need to change the code a bit and add some Generics around to make it happen the way you want.
Sotirios Delimanolis Factory suggestion might also be an option.
You can have the abstract class BasicRelation include the static method which throws an Exception. That way you will be forced to override (shadow) the static method in the subclasses when you use it.
Something like:
public abstract class BasicRelation {
public static List<..> fromSentence(String s) {
throw new RuntimeException();
}
}

groovy call private method in Java super class

I have an abstract Java class MyAbstractClass with a private method. There is a concrete implementation MyConcreteClass.
public class MyAbstractClass {
private void somePrivateMethod();
}
public class MyConcreteClass extends MyAbstractClass {
// implementation details
}
In my groovy test class I have
class MyAbstractClassTest {
void myTestMethod() {
MyAbstractClass mac = new MyConcreteClass()
mac.somePrivateMethod()
}
}
I get an error that there is no such method signature for somePrivateMethod. I know groovy can call private methods but I'm guessing the problem is that the private method is in the super class, not MyConcreteClass. Is there a way to invoke a private method in the super class like this (other than using something like PrivateAccessor)?
thanks
Jeff
The fact that you can call private methods is a bug in the Groovy language, not a feature. However, I believe this bug was introduced deliberately as a form of compromise when making some changes to the way closures behave.
Even though you can call private methods, you should not, because hopefully one day this bug will be fixed, and if your program relies on calling private methods it will be broken.
If you really insist on (ab)using this undocumented behaviour, you could try using something like ReflectionUtils to call private methods in parent classes.
Another workaround is to provide a method in the concrete class that calls the private method in the parent class. For example, the following code "works", but it still relies on accessing private members, which is bad
class Parent {
private foo() {println "foo"}
}
class Child extends Parent {
public bar() {super.foo()}
}
new Child().bar()

Categories

Resources