I have a class with a local inner class in one of its methods:
public class Outer {
String hello = "hello";
public void myMethod() {
class Inner {
public void myInnerMethod() {
System.out.println(hello);
}
}
[...really slow routine...]
(new Inner()).myInnerMethod();
}
}
I would like to test the myInnerMethod(). So I instantiate the local inner class using reflection and call the myInnerMethod() on it.
public void test() {
Object inner = Class.forName("Outer$Inner").newInstance();
inner.getClass().getDeclaredMethod("myInnerMethod").invoke(inner); // hello will be null
}
But when myInnerMethod() accesses hello, which is in the scope of the Outer class, it is null.
Is there a way to mock or otherwise provide hello to myInnerMethod()?
I know I could refactor my code by extracting the inner class or just test the public methods of Outer. But is there still a way to do it?
You would need to make some small refactoring before being able to verify the inner behavior:
1) Create a package level method that would contain the code invoked from within the myInnerMEthod:
public class Outer {
String hello = "hello";
public void myMethod() {
class Inner {
public void myInnerMethod() {
Outer.this.printHello(hello); // !!! change here
}
}
[...really slow routine...]
(new Inner()).myInnerMethod();
}
void printHello(String hello){/* */} // !! add this
}
2) Spy on the Outer class and verify the printHello has been called with the hello instance variable:
public void test() {
// Arrange
Outer outerSpy = spy(new Outer());
doNothing().when(outerSpy).printHello(anyString()); // optional
// Act
outer.myMethod();
// Assert
verify(outerSpy).printHello("hello");
}
Related
public class Outer {
public void Say(Bar bar) {
//...
}
public Outer(final Foo foo) {
//...
}
}
public interface Foo {
void blah(Bar bar);
}
public class Application {
public static void main(String[] args) {
Outer outer = new Outer(new Foo() {
#Override
public void blah(Bar bar) {
/*trying to access "outer"*/.Say(bar);
}
});
}
}
What should I do to access "outer"?
Thanks.
StackOverflow forbade me from posting this because it said my post was mainly code and this line is just a bunch of nonsense. Please ignore it.
Outer is not reachable. As the instance is created after Foo is created.
I see two ways:
1. Convert the variable outer into a static context.
2. Hand over the variable while calling method blah()
In your example, 'outer' is simply 'this'
So, here is the class with private Inner class declared inside and a private attribute.
I need to use Java reflection writing a test program in main function to execute this class.
public class Outter {
private Inner in;
public Outter(){
in = new Inner();
}
private class Inner{
private void test(){
System.out.println("test");
}
}
}
Here is test code:
my questions are listed following the statement.
public class Test
{
public static void main(String[] args) throws Exception
{
// 1. How do i create a Class type for Inner class since its modifier
// is private, if I am going to need .setAccessible() then how do i
// use it?
Class outter1 = Outter.class;
// 2. How do I pass parameters of type Inner to the Class object?
Constructor con = outter1.getConstructor(new Class[]{int.class});
// 3. Like this?
Field fields = outter1.getField("test");
fields.setAccessible(true);
// 4. Well I am lost what is the logic route for me to follow when
// using java reflection to execute a class like this!
Object temp = outter1.newInstance();
Outter outter = (Outter)temp;
System.out.println(fields.get(outter));
}
}
Here's a self-contained example of what you're trying to do.
Code you're running
try {
// gets the "in" field
Field f = Outer.class.getDeclaredField("in");
// sets it accessible as it's private
f.setAccessible(true);
// gets an instance of the Inner class by getting the instance of the
// "in" field from an instance of the Outer class - we know "in" is
// initialized in the no-args constructor
Object o = Object o = f.get(Outer.class.newInstance());
// gets the "execute" method
Method m = o.getClass().getDeclaredMethod("test", (Class<?>[])null);
// sets it accessible to this context
m.setAccessible(true);
// invokes the method
m.invoke(o, (Object[])null);
}
// TODO better handling
catch (Throwable t) {
t.printStackTrace();
}
Classes (inner/outer)...
public class Outer {
private Inner in;
public Outer() {
in = new Inner();
}
private class Inner {
private void test() {
System.out.println("test");
}
}
}
Output
test
Is it possible to access variable abc directly from a subclass?
I know its possible by changing abc to Static, but I don't want to do this.
main:
public class main {
public subclass subclass1 = new subclass();
public boolean abc = false;
public static void main(String[] args) {
// TODO Auto-generated method stub
main menu1 = new main();
}
public main(){
while(true){
if(abc = true){
System.out.println("true");
}
}
}
}
subclass:
public class subclass {
public subclass(){
.abc = true; //possible to access abc of main?
}
}
Thanks.
Your subclass class isn't subclassing main, so it can't directly access abc. It's confusing to call it subclass, because it subclasses only Object (implicitly).
It needs to have a reference to an instance of the main class, then it can access abc through that instance. That will work because abc is public.
UPDATE
Example:
public class Main
{
public subclass subclass1;
public boolean abc = false;
public static void main(String[] args)
{
Main menu1 = new Main();
menu1.subclass1 = new Subclass(menu1);
System.out.println(menu1.abc);
}
}
public class Subclass
{
private Main myMain;
public Subclass(Main main)
{
myMain = main;
myMain.abc = true;
}
}
There are a multitude of things wrong with your code.
Subclass is not a subclass of anything, in order for it to be a
subclass it must extend another class by use of the keyword extends, Bus extends Vehicle (by default all classes in
java only extend Object).
You have declared abc as public, this
means it is accessible to everyone who has an instance of the class
main by use of the dot operator on the instance. You can achieve this by creating an instance of main in your subclass
main m = new main();
public subclass() {
m.abc = true;
}
You will also have to remove public subclass subclass1 = new subclass(); from main. The way you have made these classes subclass needs main needs subclass needs main needs subclass....circular references.
You will never be able to access an instance of the class because of the while(true) inside the constructor of main. This will run forever and never allow the constructor to finish. You will have to remove the while(true) statement, you can check whether abc has indeed been changed by doing the following
main m = new main();
public subclass() {
System.out.println("Value of abc? "+m.abc);
m.abc = true;
System.out.println("Value of abc? "+m.abc);
}
This is Simple inheritance and because abc access modifier is public, you should be able to use in child class without any issue.
If you are going to access abc, then you would have to have an instance of your main class:
Main m = new Main();
m.abc = "something";
You can use simple inheritance if both classes are related. Otherwise,
m.abc= true
Would be a good option.
If you don't make abc static it will only exist in an instance (or object) of "main".
So to access it you will need to have a reference to the object.
So one thing you could do is ask for Main in SubClass's constructor (you should follow the java conventions) like:
public class SubClass {
private final Main main;
public SubClass(Main main) {
this.main = main;
main.abc = true;
}
}
public class Main {
public SubClass subClass1 = new SubClass(this);
}
or if SubClass is really only for Main's use you could make it an inner class.
public class Main {
public class SubClass {
public SubClass() {
//You can access Main's variables here and in case of ambiguity by doing
Main.this.abc = true;
}
}
}
Alternatively you can create a Main in SubClass.
public class SubClass {
public SubClass() {
Main main = new Main();
main.abc = true;
}
}
(SubClass naming is a bit weird here and I think you might want to learn a bit more about objects/instances, or OOP in general.)
You can access abc in sub class if it extends class main. Please find below a sample
public class Test {
Boolean abc = false;
Test()
{
if(abc)
{
System.out.println("Test():True");
}
else
{
System.out.println("Test():False");
}
}
void method()
{
if(abc)
{
System.out.println("Method():True");
}
else
{
System.out.println("Method():False");
}
}
public static void main(String[] args)
{
Test1 child= new Test1();
child.method();//Parent method (abc change will reflect)
Test parent = new Test();//Directly calling parent constructor so abc is false
}
}
child class
public class Test1 extends Test
{
Test1()
{
this.abc=true;
}
}
ouput will be
Test():False
Method():True
Test():False
interface TestA {
String toString();
}
public class Test {
public static void main(String[] args) {
System.out.println(new TestA() {
public String toString() {
return "test";
}
});
}
}
What is the result?
A. test
B. null
C. An exception is thrown at runtime.
D. Compilation fails because of an error in line 1.
E. Compilation fails because of an error in line 4.
F. Compilation fails because of an error in line 5.
What is the answer of this question and why? I have one more query regarding this question. In line 4 we are creating an object of A. Is it possible to create an object of an interface?
What you are seeing here is an anonymous inner class:
Given the following interface:
interface Inter {
public String getString();
}
You can create something like an instance of it like so:
Inter instance = new Inter() {
#Override
public String getString() {
return "HI";
}
};
Now, you have an instance of the interface you defined. But, you should note that what you have actually done is defined a class that implements the interface and instantiated the class at the same time.
test should be the output. This is an example of an anonymous inner class.
This is a very common pattern used with the Comparator interface as an emulation of closures.
Try this too... The name of anonymous class is generated!
Inter instance = new Inter() {
public String getString() {
return "HI" + this.getClass();
}
};
The trick is not only about the anonymous inner class, this prints test cause it overrides the toString method and while System.out.println a Object it implicit call it's toString method.
We can create an object of an anonymous class, that implements the interface:
Anonymous classes enable you to make your code more concise. They enable you to declare and instantiate a class at the same time. They are like local classes except that they do not have a name. Use them if you need to use a local class only once.
If you have an interface, that declares one method toString, you can first create a class, that implements this inerface, and then create an object of this class:
interface TestA {
String toString();
}
class TestB implements TestA {
#Override
public String toString() {
return "test";
}
}
public class Test {
public static void main(String[] args) {
System.out.println(new TestB());
}
}
Or you can create an object of an anonymous class to simplify this code:
interface TestA {
String toString();
}
public class Test {
public static void main(String[] args) {
System.out.println(new TestA() {
#Override
public String toString() {
return "test";
}
});
}
}
In both cases it prints "test".
I don't know the significance of this question. If this is an interview question, then I can say it's okay. But in real time it's not the right approach to implement an inheritance.So coming to the answer of the question, here what you are doing is an anonymous inner class .
Here you are instantiating a class and implementing the inheritance by writing,
System.out.println(new TestA() {
public String toString() {
return “test”;
}
});
and ofcourse the result would be test
This question already has answers here:
Why is an anonymous inner class containing nothing generated from this code?
(5 answers)
Closed last year.
If I have an inner class, like this:
public class Test
{
public class Inner
{
// code ...
}
public static void main(String[] args)
{
// code ...
}
}
When I compile it, I expect it should generate two files:
Test.class
Test$Inner.class
So why do I sometimes see classfiles like SomeClass$1.class, even though SomeClass does not contain an inner class called "1"?
The SomeClass$1.class represent anonymous inner class
hava a look at the anonymous inner class section here
You'll also get something like SomeClass$1.class if your class contains a private inner class (not anonymous) but you instantiate it at some point in the parent class.
For example:
public class Person {
private class Brain{
void ponderLife() {
System.out.println("The meaning of life is...");
}
}
Person() {
Brain b = new Brain();
b.ponderLife();
}
}
This would yield:
Person.class
Person$Brain.class
Person$1.class
Personally I think that's a bit easier to read than a typical anonymous class especially when implementing a simple interface or an abstract class that only serves to be passed into another local object.
to build up on hhafez : SomeClass$1.class represents anonymous inner classes.
An example of such a class would be
public class Foo{
public void printMe(){
System.out.println("redefine me!");
}
}
public class Bar {
public void printMe() {
Foo f = new Foo() {
public void printMe() {
System.out.println("defined");
}
};
f.printMe();
}
}
From a normal Main, if you called new Bar().printMe it would print "defined" and in the compilation directory you will find Bar1.class
this section in the above code :
Foo f = new Foo() {
public void printMe() {
System.out.println("defined");
}
};
is called an anonymous inner class.