How access private methods from anonymous class? - java

Suppose I have class:
MyObject b = new MyObject(){
private void method(){}
}
Is it possible to get method() by reflection? For toString I can write:
MyObject.class.getMethod("toString");
But what about for new created private method?

You have to invoke Object#getClass() on b reference to get the anonymous class, where the method is declared. MyObject.class will give you Class<MyObject>, which is not possibly what you want.
And then use Class#getDeclaredMethod() to get the private method:
Method method = b.getClass().getDeclaredMethod("method");
method.setAccessible(true);
method.invoke()

You can use it with:
Method method = b.getClass().getDeclaredMethod("method");
Here b.getClass() will return the class that the compiler generated for you for the anonymous inner class.
I can't easily imagine a situation in which that's a good approach, however.
Note that if you use a local named class, you don't even need to use reflection to call the method:
public class Test {
public static void main(String[] args) {
class Foo {
private void doSomething() {
System.out.println("Yes!");
}
};
Foo foo = new Foo();
foo.doSomething();
}
}
If you could give us more context about why you want this, we could probably be of more help in finding the best solution.

Related

Java Inheritance: Overwritten or hidden methods

When a class extends another, it inherits all methods and variables of the superclass. Both methods and variables can be used differently in the subclass, if you define it differently in the subclass with the same signature.
Now Oracle distincts between overwriting and hiding (http://docs.oracle.com/javase/tutorial/java/IandI/override.html).
It says that an instance method overwrites its superclass's method, while a class method hides it.
"The distinction between hiding and overriding has important implications. The version of the overridden method that gets invoked is the one in the subclass. The version of the hidden method that gets invoked depends on whether it is invoked from the superclass or the subclass."
Lets assume I have 2 classes Yes and Maybe. Yes extends Maybe.
Maybe has String a.
class Maybe {
String a;
public static void printOut() {
System.out.println("Maybe");
}
public void printAndSet() {
a = "Maybe";
System.out.println(a);
}
}
class Yes extends Maybe {
public static void printOut() {
System.out.println("Yes");
}
pubilc void printAndSet() {
a = "Yes";
}
}
class Print{
public static void mail(String[] args) {
Maybe m = new Maybe();
Yes y = new Yes();
Maybe.printOut();
Yes.printOut();
m.printAndSet();
y.printAndSet();
}
And I say: It will print out
maybe
yes
maybe
yes
But after I read the Oracle article I thought it would have to print out:
yes
yes
maybe
yes
Because the instance method overwrites its superclass method.
I'm quite sure I am right with the output, but I'm sure aswell, that Oracle knows
better so I'm thinking I just didn't understand the article.
It can't be true that when I call an instance method from an object of a superclass, that it uses the overwritten method.
So I do not understand why to distinguish overwriting and hiding!
Can someone help out?
Edit; Inserted code instead of describing the classes!
Static methods can't be overridden at all. They're not called polymorphically, since they don't act on an instance of the class, but on the class itself.
If you call Maybe.printOut(), it will call the static printOut() method defined in Maybe. The fact that there is also a method printOut() defined in Yes is irrelevant: those two methods have nothing in common, except their name.
Note that you could confirm or infirm your doubts by simply writing a program and executing it.
The problem with hiding methods only occurs when you start calling static methods on an instance of an object. This is very bad practice, and should never be done. If you don't respect this rule, and have the following:
Maybe m = new Maybe();
Maybe y = new Yes();
m.printOut(); // DON'T DO THAT: it should be Maybe.printOut();
y.printOut(); // DON'T DO THAT: it should be Maybe.printOut() or Yes.printOut();
the result will be maybe maybe, because in the case of static methods, what counts is not the concrete type of the objects (Maybe and Yes), but their declared type (Maybe and Maybe).
public class Parent {
public String test(){
return "p";
}
public static String testStatic(){
return "sp";
}
}
public class Child extends Parent {
public String test(){
return "c";
}
public static String testStatic(){
return "sc";
}
}
public class Demo{
public static void main(String[] args) {
Parent p =new Parent();
Child c = new Child();
Parent pc = new Child();
System.out.println(p.test());
System.out.println(c.test());
System.out.println(pc.test());
//Although this is not the correct way of calling static methods
System.out.println(p.testStatic());
System.out.println(c.testStatic());
System.out.println(pc.testStatic());
}
}
OUTPUT will be: - (static method vs instance method)
p
c
c
sp
sc
sp
Take the following example, based on your example:
public class SO11720216 {
static class Maybe {
public static void hidden() { System.out.println("static maybe"); }
public void overwritten() { System.out.println("instance maybe"); }
public void inherited() { hidden(); }
public void called() { overwritten(); inherited(); }
}
static class Yes extends Maybe {
public static void hidden() { System.out.println("static yes"); }
public void overwritten() { System.out.println("instance yes"); }
}
public static void main(String[] args) {
Maybe m = new Maybe();
Yes y = new Yes();
m.called(); /* prints:
instance maybe
static maybe
*/
y.called(); /* prints:
instance yes
static maybe
*/
Yes.hidden(); /* prints: static yes */
y.hidden(); /* bad style! prints: static yes */
}
}
The call to overwritten will be overwritten by each derived class. So every method will use the implementation belonging to the current object. On the other hand, the call to hidden will always use the implementation of the defining class. Hence Maybe.called will always call Maybe.hidden, and never Yes.hidden. To call Yes.hidden, you'll have to do so from within a method in Yes, or using a qualified name.
To phrase this differently:
To overwrite a method means that whenever the method is called on an object of the derived class, the new implementation will be called.
To hide a method means that an unqualified call to that name (like the hidden() call in the inherited() method of my above example) in the scope of this class (i.e. in the body of any of its methods, or when qualified with the name of this class) will now call a completely different function, requiring a qualification to access the static method of the same name from the parent class.
Perhaps your confusion comes from the fact that you assumed overwriting to affect all calls to the method, even for objects of the base class.

Static And Non Static Method Intercall In Java

I am clearing my concepts on Java. My knowledge about Java is on far begineer side, so kindly bear with me.
I am trying to understand static method and non static method intercalls. I know --
Static method can call another static method simply by its name within same class.
Static method can call another non staic method of same class only after creating instance of the class.
Non static method can call another static method of same class simply by way of classname.methodname - No sure if this correct ?
My Question is about non static method call to another non staic method of same class. In class declaration, when we declare all methods, can we call another non static method of same class from a non static class ?
Please explain with example. Thank you.
Your #3, is correct, you can call static methods from non-static methods by using classname.methodname.
And your question seems to be asking if you can call non-static methods in a class from other non-static methods, which is also possible (and also the most commonly seen).
For example:
public class Foo {
public Foo() {
firstMethod();
Foo.staticMethod(); //this is valid
staticMethod(); //this is also valid, you don't need to declare the class name because it's already in this class. If you were calling "staticMethod" from another class, you would have to prefix it with this class name, Foo
}
public void firstMethod() {
System.out.println("This is a non-static method being called from the constructor.");
secondMethod();
}
public void secondMethod() {
System.out.println("This is another non-static method being called from a non-static method");
}
public static void staticMethod() {
System.out.println("This is the static method, staticMethod");
}
}
A method is and should be in the first regard be semantically bound to either the class or the instance.
A List of something has a length or size, so you ask for the size of special List. You need an object of that class to call .size ().
A typical, well known example of a static method is Integer.parseInt ("123");. You don't have an Integer instance in that moment, but want to create one.
If, at all, we would bind that method to an instance, we would bind it to a String instance - that would make sense:
int a = "123".parseInt ();
That would have been a reasonable choice, but it would mean that similar methods for float, double, long, short, Boolean and maybe every class which has a symmetric "toString" method would have to be put into String. That would have meant a zillion of extensions to the String class.
Instead String is final, so a reasonable place to put such a method is the target class, like Integer, Float and so on.
not sure that I understand the question correctly, but non-static methods are the standard way to design classes in OO. Maybe this sample will help spark the discussion:
public class MySampleClass{
private void methodA(){
System.out.println('a called');
}
public void methodB(){
this.methodA();
staticMethod(this);
}
private static void staticMethod( MySampleClass inst ){
inst.methodA();
}
}
You can call non-static method from non-static method using explicitly reference to object on which you want to call that method someObject.method, or without specifying that object someMethod() (in this case it will be invoked on same object that you are invoking current non-static method).
Maybe this will show it better
class Demo {
private String name;
public Demo(String n) {
name = n;
}
public String getName() {// non static method
return name;
}
public void test(Demo d) {// non-static method
System.out.println("this object name is: "+getName());// invoking method on this object
System.out.println("some other object name is: "+d.getName());// invoking method on some other object
}
//test
public static void main(String[] args) {
Demo d=new Demo("A");
Demo d2=new Demo("B");
d.test(d2);
}
}
output:
this object name is: A
some other object name is: B
public class TestClass{
public static void testStatic(){
System.out.println("test1");
}
public void testNonStatic(){
System.out.println("test2");
}
public void test1(){
// both is valid
testStatic();
TestClass.testStatic();
// this is valid, cause it can call the method of the same instance of that class
testNonStatic();
this.testNonStatic();
// this is not valid, cause without a concrete instance of a class you cannot call
// non static methods
TestClass.testNonStatic();
}
public static void test2(){
// again these are both correct
testStatic();
TestClass.testStatic();
// this doesn't work, cause you cannot call non static methods out of static methods
testNonStatic();
this.testNonStatic();
// this instead does work cause you have a concrete instance of the object
TestClass myTestClass = new TestClass();
myTestClass.testNonStatic();
// this still doesn't work
TestClass.testNonStatic();
}
}

Define the methods of anonimous class created inside a method from the method caller

in a class i have
A a = new A(){
stuffhere
};
now i found that i need to create the new A inside a method and return it, but i have to define the stuffhere from the class caller. Is there a way in java to do so? Something like
A a = createAClass(){
stuffhere
};
public A createAClass()[T]{
return new A(){T};
}
or something similar. I would prefer not to use an interface to pass to the create method, since my anonymous classes not only override methods, but also adds attributes and new functions, and i don't think i can pass them with an interface..
Any thought?
EDIT for the -1ers (a simple comment would suffice)
with the syntax [T], obviously wrong, i meant something that can pass a generic code, let's say a copy-paste of code.
createAClass()[int a; String b; #override public void mymethod(){dosomethigb;} public void dosomethingelse(){dosomethingelse;}];
would work like
public A createAClass(){
return new A()
{
int a;
String b;
#override public void mymethod()
{dosomethigb;}
public void dosomethingelse()
{dosomethingelse;}};
};}
but if i write in another part of the program
createAClass()[float c; List d; public void yourmethod(){dosomething2;} #override public void dosomethingelse(){dosomethingelse2;}];
it would instead work like
public A createAClass(){
return new A()
{
float c;
List d;
public void yourmethod()
{dosomething2;}
#override public void dosomethingelse()
{dosomethingelse2;}
};}
My bad, i choose a bad may of making an example, but i thought it was the clearest way. Maybe i should have used X instead of T?..
Long story short:
i want create an anonymous class inside a method, but define what the anonymous class does in the method caller, and not inside the method(like the title says)
EDIT2:
i know i can't access the new methods from the class, what i do now is create an anonymous class, add a few attributes and method, and then use them in an overridden method. The added methods are not a problem, since i can make the method caller to pass an interface that is called by the overridden method in the anonymous class created, the problems are the attributes. I don't know how to add them in the anonymous class passing them from the method caller.
Something like the following usually works:
public A createAClass(final String value){
return new A(){
// some code here that can access value
};
}
If you are looking for something else, please clarify the question.
Edit
Answer is no you can't do that. You are trying to create an A with no defined API for A. Even if you could do what you propose, how would any user of A know what methods / fields are available if A is not defined somewhere? For A to be useful, you need to have an API that A implements.
Not sure whether fully understood by me. But the pattern is like this:
public class Here {
private int stuff;
public class A {
private A() { ... }
... ++stuff; ...
}
public A createA() { ... }
}
...
Here here = ...
A a = here.createA();
AFTER QUESTION EDITED:
The simplest way is to override a method:
final Object stuff = ...;
A a = new A() {
#Override
protected void onSomeEvent() {
... stuff.toString();
}
}
Then A can call onSomeEvent.

Java passing subclass instance data to superclass constructors

Does anybody know if there's a way in Java to set the value of an instance variable in a subclass before calling the superclass constructor. I have a brief schematic below of what I'm trying to accomplish -- I need to set up the instance variables defined in the superclass differently depending on the subclass type, but I still want to be able to share common non-constructor code among different instances of the subclass.
Is there any clean way to do this, maybe some sort of coding pattern that I'm missing or something? Thanks in advance for any ideas.
public abstract class ConstraintSatisfactionProblem {
final Set<Variable> variables;
final Set<Constraint> constraints;
public Foo() {
this.variables = setupVariables();
this.constraints = setupConstraints();
}
public abstract Set<Variable> setupVariables();
public abstract Set<Constraint> setupConstraints();
public Map<Variable, Constraint> solve() { ... }
}
public class WordSquare extends ConstraintSatisfactionProblem {
final int size;
final static Set<Character> domain = ...;
public WordSquare() {
super(); // can I simulate calling super() after setting this.value = 4?
this.value = 4;
}
public Set<Variable> setupVariables() {
this.variables = new HashSet<Variable>();
for(int row = 0; row < size; ++row) {
for(int col = 0; col < size; ++col) {
variables.add(new Variable<Pair, Character>(new Pair(row, col), domain);
}
}
return this.variables;
}
public Set<Constraint> setupConstraints() {
// setup code specific to this problem
}
}
public class Cryptarithmetic extends ConstraintSatisfactionProblem {
final String problem;
public Cryptarithmetic(String problem) {
super();
this.problem = problem;
}
public Set<Variable> setupVariables() {
this.variables = new HashSet<Variable>();
for(char c : problem.toCharArray()) {
variables.add(new Variable<Character, Integer>(c, getDomain());
}
}
return this.variables;
}
public Set<Constraint> setupConstraints() {
// setup code specific to this problem
}
}
Firstly, please don't.
Secondly, really it's a really bad idea. Don't. Think about what you are trying to do in a broader context.
If you absolutely must do, you can stash it in a ThreadLocal. You can call a (non-instance) method by evaluating an expression the result of which is passed to a super() or this() (possibly the only reason why you need a second, private constructor that possibly takes a Void (capital 'V') argument). It's so evil, I am not going to even write the code down.
In your edited example code, just pass the sets into a protected constructor. If you have many arguments possibly some subclasses being special about some arguments, you might want to wrap all the arguments into a single argument object.
There is another really hacky approach, so long as you have -target 1.4 or later (which you should do!). Make the subclass an inner class (possibly anonymous). The references to the outer this and other captured variables are available before calling the super constructor.
public class Outer {
// What a hack!
private static abstract class Base {
Base() {
hello(); // Calling a virtual method in a constructor - poor form.
}
abstract void hello();
}
public static void main(String[] args) {
// Do not do this.
final String hi = "Hi!";
new Base() {
void hello() {
// Really, don't do it.
System.err.println(hi);
}
};
}
}
Place the common code you want to run in a protected method instead of in the constructor. Call that method when you wish.
You should never call any "alien" method (ie. overridable method of this class, or any method from any other class) form within a constructor. As long as the object is not fully initialized, you may have side-effects like the one you see.
In your case, in the subclass constructor, super() is called even before the "value" is set to 4. This means, the superclass constructor is called, then calls the "setup" method, while the "value" is still at 0.
Only once the superclass constructor returns, the "value" is set to 4. And it's too late then.
What I would recommend, is to set the "o1" variable to protected, so that subclasses can set its value themselves.
In Java, if you want to call a base class's constructor, you have to do it on the first line of your sub-class's constructor. So the answer is no, you can't set this.value before calling the super class's constructor.
But your sub-class's setup() method is already called in the super's constructor. Why don't you set your value there?
UPDATE:
Sorry, I didn't pay attention that your 'setup()' method returns a value. What you could do is make an abstract init() method in your super class, and call it in your super constructor before you call the setup() method. This way sub-classes will be forced to implement init(), and you would know that that is the place to initialize any sub-class's members before they are used in your super-class.
That being said, this approach does not force safety on you. When you call the super constructor from your sub-constructor, the sub-class instance is just starting to get created. It still needs to run the rest of the code in the sub-constructor before the object is safely created.
And in this situation, the super-constructor goes and calls the init() method on your just-in-the-process-of-creation sub-class. This means that if you go with approach, you have to be extra careful about what you do in the init() class.
Like others have said, don't do this. If you want to share some code between these classes, try containment/encapsulation instead of inheritance.
public class Foo {
private final Object o1;
public Foo(Object o) {
o1 = o;
}
public void complexMethodCommonToAllSubclassesOfFoo() { ... }
}
public class Bar {
private final int value;
private final Foo foo;
public Bar() {
super();
this.value = 4;
this.foo = new Foo( new Object() ); // or whatever
}
// If you need to expose complexMethodCommonToAllSubclassesOfFoo to clients of this class, just add the method and delegate to foo like this
public void complexMethodCommonToAllSubclassesOfFoo() {
foo.complexMethodCommonToAllSubclassesOfFoo();
}
}
I need to set up the instance variables defined in the superclass differently depending on the subclass type, but I still want to be able to share common non-constructor code among different instances of the subclass.
In that case, create a protected constructor in the superclass, and pass all of the customized values to it when you construct the subclass.

Anonymous Class in Java

Is it possible to create an anonymous class in Java like this:
public static void main(String[] args) {
AnonymousClass a = new AnonymousClass() {
int whatever = 1;
};
System.out.println(a.whatever);
}
I thought that this would be working but it doesn't. Do I misunderstand something with anonymous classes or is there only a syntax error?
You can do it this way:
public static void main(String[] args) {
System.out.println(new Object() {
int whatever = 1;
}.whatever);
}
That is, you can only dereference the fields and method directly from the instantiation expression. [Edit: Per the comments, you can use it where the compiler infers the type for you - which happens to be the instantion expression, or as a return value from a generic method you pass it to.] You can't store it in a variable and use fields/methods there, so it's not as useful as anonymous classes in e.g. C#.
Edit: You can, as previously stated by others, declare a method-local class:
public static void main(String[] args) {
class Local {
int whatever = 1;
}
Local local = new Local();
System.out.println(local);
}
Slightly wordy, though, and like non-static inner classes and regular anonymous classes, it retains an implicit reference to the enclosing this (in non-static methods).
If it was possible, we would not call them anonymous anymore: your example defines a class with a name: Anonymous. You may define an inner class with a name like this:
public static void main(String[] args) {
class NotAnonymous {
public int whatever = 1;
}
NotAnonymous na = new NotAnonymous();
System.out.println(na.whatever);
}
For this to work, AnonymousClass needs to be an Interface or a Class:
private interface AnonymousClass {
}
public static void main(String[] args) {
AnonymousClass a = new AnonymousClass() {
int whatever = 1;
};
System.out.println(a.whatever); // this won't work
}
EDIT
Corrected, as correctly stated in the comment, whatever won't accessible / present.
You are referring original anonymous class instance, which has no field "whatever" - so you can not reference it this way.
You can create your class like this, sure. However, the a.whatever call will fail, because the object type is still AnonymousClass, and it does not define whatever as an attribute.
If you overwrite some method or attribute that is already defined in the AnonymousClass class or interface, the object will use your implementation from the anonymous class instead of the old one, but not if you introduce new methods or attributes.

Categories