I want to invoke a private method which takes abstract class parameter and that abstract class is hidden (I can not access it directly). I need to get the updates whenever methods of abstract class are invoked by some other class.
Class I am refereeing to is:
public class A{
private void method(AbstractClassA object){ ... }
// please note below class is hidden. I can not do A.AbstractClassA . I have to access it using reflection unless there is any other way
public abstract class AbstractClassA {
//I am interested in getting this int whenever someone else calls the progressUpdate
public void progressUpdate(int update);
}
}
I am trying to access like this:
public class myClass{
Class<?> abstractClass = Class.forName("<package>.A$AbstractClassA");
A a = new A();
Method someMethod = a.getDeclaredMethod("method", (Class[])null);
someMethod.setAccessible(true);
someMethod.invoke(a, <something which I don't know>); //how to pass paramerts here so that I get all callbacks whenever progressUpdate is called by someone else and "update" parameter is changed.
}
public class SubClassA extends A {
private SubClassAbstractA subClassA;
public SubClassA() {
this.subClassA = new SubClassAbstractA();
}
public class SubClassAbstractA extends AbstractA {
#Override
public void progressUpdate(int update) {
SubClassA.this.progressUpdate(update);
}
}
public void progressUpdate(int update) {
//do things with int
}
public void someMethod() {
Class<?> clazz = A.class;
Method method = clazz.getDeclaredMethod("method");
method.setAccessible(true);
method.invoke(this, subClassA);
}
}
Related
I have an abstract base test class and an interface. Inside the test class, a private field of type interface is declared.
abstract class FibonacciTest {
*private FibonacciImplementation fibonacciImplementation;*
public FibonacciImplementation getImplementation(){
return this.fibonacciImplementation;
}
protected void setImplementation(FibonacciImplementation fibimplem){
this.fibonacciImplementation = fibimplem;
}
abstract void createFibonacciImplementation();
#BeforeEach
void createImplementation(){
createFibonacciImplementation();
}
#Test
void invalidPosition(){
assertEquals(new BigInteger("-2"),
fibonacciImplementation.calculateFib(-2));
}
The interface is:
public interface FibonacciImplementation {
BigInteger calculateFib(int position);
}
The sub test classes for the base test class is something like this:
public class RecursiveFibonacciTest extends FibonacciTest{
#BeforeEach
void createFibonacciImplementation(){
fibonacciImplementation = new RecursiveFibonacciImplementation();* error is here
}
}
The recursivefibonacciImplentation is this:
public class RecursiveFibonacciImplementation implements FibonacciImplementation {
#Override
public BigInteger calculateFib(int position) {
if(position < 0 )
return new BigInteger("" + position);
if(position == 1 || position == 0)
return new BigInteger("1");
return calculateFib(position-1).add(calculateFib(position-2));
}
}
The problem I have is that when in the sub test class, the compiler complains that i am trying to access a private field. The private FibonacciImplementation fibonacciImplementation; field. How do i remove that error. How do I access fibonacciImplementation? The getter and setter does not seem to work.The compiler says fibonacciImplementation has private access in FibonacciTest.
Mind you, the requirement is that it has to be a private field.
Do you really need a field at all? If instances of the implementing classes are not expensive to create, you can just get an instance only when you need it, no need to store it in a field.
abstract class FibonacciTest {
abstract FibonacciImplementation createFibonacciImplementation();
#Test
void invalidPosition(){
assertEquals(new BigInteger("-2"),
createFibonacciImplementation().calculateFib(-2));
}
}
public class RecursiveFibonacciTest extends FibonacciTest{
#Override
FibonacciImplementation createFibonacciImplementation(){
return new RecursiveFibonacciImplementation();
}
}
private means it can only be accessed from within the same class. If you want a field only to be accessible by sub-classes, you'll want to mark it as protected.
Change this:
private FibonacciImplementation fibonacciImplementation;
To this:
protected FibonacciImplementation fibonacciImplementation;
In the FibonacciTest class.
Let's suppose I have a class OuterClass which has a method classMethod() and an nested interface NastedInterface which in its turn has a method callback(). So how can I call the method of the interface callback() in the method of class classMethod()?
My goal is to be able to implement OuterClass.NastedInterface in other classes and do some operations in the callback() method, which will be called when the classMethod() will be called in OuterClass.
The code will look like something like this.
public class OuterClass {
public void classMethod(){
if(SOME_CONDITION){
\\ here I want to call the **callback()** method of **NastedInterface**
}
}
public interface NastedInterface {
void callback();
}
}
And the class that will implement this interface should look like something like this.
public class TestClass implements OuterClass.NastedInterface {
#Override
public void callback (){
DO SOMETHING....
}
}
Basically I want to create a callback mechanism, such as I have used many times in Android. For example the View.OnClickListener or all other such kind of ON_SOMETHINK_LISTENER s.
May be I am going in wrong direction, and I need to create such a mechanism in other way?
Put a member variable in your OuterClass that holds an instance of NestedInterface. Add a setter method that sets that variable, and make it public.
Make sure the check that the member isn't null before calling callback.
Outerclass needs to have a reference to the TestClass for this work.
So:
public class OuterClass {
private NastedInterface interfaceToCall;
public void classMethod(){
if(SOME_CONDITION){
\\ here I want to call the **callback()** method of **NastedInterface**
if(interfaceToCall != null)
{
interfaceToCall.callback();
}
}
}
public interface NastedInterface {
void callback();
}
}
Thanks to everyone for answers, I solved the problem and every answer here helped me in some way. But as the solution was not exactly how how suggested in answers, I will write it here for people who may need it in the future.
public class OuterClass {
private NastedInterface nastedInterface;
//In the constructor I am assigning the reference of the parent class
// of some other classes in my app which all may need to be notified when
// **callback()** has happened
public OuterClass(){
nastedInterface = TestClassParent.getInstance;
}
public void classMethod(){
if(nastedInterface != null){
nastedInterface.callback();
}
}
public interface NastedInterface {
void callback();
}
}
So here I have a class which will be the parent of some other classes and will implement NastedInterface.
public class TestClassParent implements OuterClass.NastedInterface {
private static TestClassParent instance;
public static TestClassParent getInstance(){
if(instance == null){
instance = new TestClassParent();
}
return instance;
}
#Override
public void callback(){
//I will override it in subclasses and do what I need in each class
}
}
And after this I can receive callback() event in any class that extends TestClassParent. For example:
public class TestClass1 extends TestClassParent {
#Override
public void callback (){
DO SOMETHING....
}
}
and
public class TestClass2 extends TestClassParent {
#Override
public void callback (){
DO SOMETHING ELSE....
}
}
I have tree classes.
class MyObject{
public void DoSomething()
{
here I need to call method add from class base.
}
}
class base
{
protected final void add(){}
}
class extended extends base {
private MyObject pObject = new MyObject();
...
{
pObject.DoSomething();
}
}
I could have created class for each variation that extends class extended, but the type what I need to use becomes available only after class extended is already initiated.
How do I call base.add() from MyObject inner method?
You can do it in a couple of ways:
Have a reference of your extended class in MyObject class. When you instantiate MyObject variable in extended class, pass it the reference of extended.
Something like this:
class MyObject{
private base baseObj;
public MyObject(base baseObj){
this.baseObj = baseObj;
}
public void DoSomething()
{
//here I need to call method add from class base.
//use baseObj to call the methods
}
}
class base
{
protected final void add(){}
}
class extended extends base {
private MyObject pObject;
...
public extended(){
pObject = new MyObject(this);
}
{
pObject.DoSomething();
}
}
Declare the methods in base class static. This way you can call the methods without requiring an instance of the base class.
Something like this:
class MyObject{
public void DoSomething()
{
//here I need to call method add from class base.
//call like this
base.add();
}
}
class base
{
protected static final void add(){}
}
class extended extends base {
private MyObject pObject;
...
public extended(){
pObject = new MyObject(this);
}
{
pObject.DoSomething();
}
}
One more thing: This is off-topic, but you might want to read about Java Naming Conventions. Having class names start with lowercase is something that you wouldn't find in the naming conventions.
dummy code like this:
class MyObject{
public void DoSomething(Base base)
{
base.add();
}
}
class extended extends base {
private MyObject pObject = new MyObject();
...
{
pObject.DoSomething(this);
}
}
I'm not sure if my question title describes my situation aptly, so my apologies if it doesn't! Anyway, let's say I have the following code snippet (visibility is as stated):
public class ChildClass extends ParentClass {
// more code
private void myMethod() {
MyClass mine = new MyClass() {
public void anotherMethod() {
// insert code to access a method in ParentClass
}
};
}
}
Is it possible for code within anotherMethod() to access a protected method found in ParentClass? If so, how can this be done?
I've tried something like...
(ParentClass.this).parentMethod();
...but obviously it doesn't work due to scope issues.
This compiles fine:
class MyClass {
}
class ParentClass {
protected void parentMethod() {
}
}
class ChildClass extends ParentClass {
private void myMethod() {
MyClass mine = new MyClass() {
public void anotherMethod() {
parentMethod(); // this works
}
};
}
}
A non-static inner class can access all methods of the enclosing class as if it were it's own methods:
public class Test {
public int getOne() {
return 1;
}
public class Inner {
public int getEnclosingOne() {
return getOne(); // this works...
}
}
}
A static inner class can not, as a static inner class is not bound to an instance of the parent class. That can only call static methods on the enclosing class.
As for methods when taking into account inheritance, an method in a non-static inner class can use all the methods of the enclosing (outer) class.
The interesting part is Test2.super.getOne() which indeed obtains getOne() from Test2.super, which is a Test. This is just like Test2 would access the method, namely using super though prefixed with Test2 to indicate you're accessing the namespace of the outer class.
public class Test2 extends Test {
public int getInnerOuterParentOne() {
Inner2 inner2 = new Inner2();
return inner2.getOuterParentOne();
}
public int getInnerOuterOne() {
Inner2 inner2 = new Inner2();
return inner2.getOuterOne();
}
public int getOne() {
return 2;
}
public class Inner2 {
public int getOuterOne() {
return getOne();
}
public int getOuterParentOne() {
return Test2.super.getOne();
}
}
public static void main(String[] args) {
Test2 test2 = new Test2();
System.out.println(test2.getInnerOuterOne()); // 2
System.out.println(test2.getInnerOuterParentOne()); // 1
}
}
There is no way to access "parent class method" in Java, irrelatively to visibility (except for super.parentMethod() in subclass's parentMethod()).
That is, if ChildClass overrides parentMethod(), there is no way to call ParentClass.parentMethod() (bypassing ChildClass.parentMethod()) from other methods of ChildClass.
However, if ChildClass doesn't override parentMethod(), that method is inherited by ChildClass, so that you can access it as a ChildClass's method, i.e. simply as parentMethod().
Ok, maybe this is a stupid question. But i'm just wondering if this can be done in java.
abstract public class ParentClass<T> {
abstract public T getTest();
}
in the subclass
public class SubClass extends ParentClass<MyObject> {
public MyObject getTest() {
// I can return the object with class MyObject
return null;
}
}
My question is can I return the class type in the child method? I mean, is it can be done by adding some code in the ParentClass, so I can do this below?
For example
public class Sub1Class extends parentClass<Object1> {
public Object1 getTest() { }
// I want to have a method that return it's class in the superclass
public Sub1Class getItClassObject() { }
}
other example
public class Sub2Class extends parentClass<Object2> {
public Object2 getTest() { }
// I want to have a method that return it's class in the superclass
public Sub2Class getItClassObject() { }
}
one example again
public class Sub3Class extends parentClass<Object3> {
public Object3 getTest() { }
// I want to have a method that return it's class in the superclass
public Sub3Class getItClassObject() { }
}
if you see, method getItClassObject in Sub1Class, Sub2Class and Sub3Class will follow it's class. But I don't want to add same method for every subclass, just want to add some code (if feasible) in the ParentClasss, so in the subclass, I just can call getItClassObject directly without write all the code in every subclass.
Usually I add method in ParentClass like this.
abstract public class ParentClass<T> {
abstract public T getTest();
public Object getItClassObject() { }
}
so in the subclass I just instance the class, but I have to cast again :(
Sub1Class sub1Class = new Sub1Class();
Sub1Class after1Cast = (Sub1Class) sub1Class.getItClassObject();
Sub2Class sub2Class = new Sub2Class();
Sub2Class after2Cast = (Sub2Class) sub2Class.getItClassObject();
I think it cannot be done in java. But I don't know if there is a clue to solve this. Thanks
This is what you want I think. The following compiles:
abstract class A {
public abstract A getA();
}
class B extends A {
// Declared to return a B, but it still properly overrides A's method
#Override
public B getA() {
return new B();
}
}
class C extends A {
// Declared to return a B, but it still properly overrides A's method
#Override
public C getA() {
return new C();
}
}
As you can see, A declares that the getA() method returns an A. But, you can restrict the return type in subclasses as shown.
I'm not sure if I understand your intent correctly, but I think the built-in Object.getClass() method will do what you want. Given classes defined as:
public abstract class ParentClass<T> {
public abstract T getTest();
}
class SubClassString extends ParentClass<String> {
public String getTest() {
return "";
}
}
class SubClassInteger extends ParentClass<Integer> {
public Integer getTest() {
return Integer.valueOf(0);
}
}
getClass() will return the correct run-time class
public static void main(String[] args) {
SubClassString subString = new SubClassString();
// displays "class SubClassString"
System.out.println(subString.getClass());
SubClassInteger subInteger = new SubClassInteger();
// displays "class SubClassInteger"
System.out.println(subInteger.getClass());
ParentClass<?> parentInstance = new SubClassInteger();
// displays "class SubClassInteger"
System.out.println(parentInstance.getClass());
}
The only way I can think of is by telling the parent class what the subclass is when you extend it (just like you did with 'T'). Eg:
public abstract class ParentClass<T,U> {
abstract public T getTest();
abstract public U getItClassObject();
}
They you define your subclass like so:
public class Sub1Class extends ParentClass<Object1,Sub1Class> {
public Object1 getTest() { }
public Sub1Class getItClassObject() { }
}
Then you can do what you want without the typecast:
Sub1Class sub1Class = new Sub1Class();
Sub1Class after1Cast = sub1Class.getItClassObject();
If your objects have no-arg constructors (or some consistent form of constructor across all of them), you can use reflection to do it. Some pseudocode would be
public class MyClass {
public MyClass instantiateType() {
Class<?> actualClass = getClass();
return actualClass.newInstance();
}
}
This is using the runtime type of the class, so subclasses will return their type. This works only for a no-arg constructor though.