public class MyClass {
public static void main(String[] args) {
MyClass myC = new MyClass();
innerClass inC = myC.new innerClass("inner");
// innerClass inC2 = new innerClass("in"); = ERROR
// innerClass inC3 = MyClass.new innerClass("inner"); = ERROR
// I wonder why the following command in line 15 works flawlessly:
// now we can easily access the inC object and its variable directly. But why?
// When we created it before, we could only do this through the myC object!
System.out.println(inC.name);
// System.out.println(myC.inC.name); = ERROR = so inC is not an instance-variable of myC object
// System.out.println(MyClass.inC.name); = ERROR, "static context..."
}
public class innerClass { // not static! Intentionally.
public String name;
public innerClass(String name) {
this.name = name;
}
}
}
What kind of strange class structure is this?
Resolved
Comments (13)
- Popular
- New
- Old
You must be signed in to leave a comment
Lisa
23 December 2021, 09:04useful
In level 23 or 24 that's what you'll learn... I modified and commented your code a little bit
+2
Guadalupe Gagnon
23 December 2021, 15:30useful
To add on:
Gellart, you have used inner classes already, though you probably never realized it. There is a certain inner class that is very popular in the Collections class..... the Iterator. All collections (Lists, Maps, Sets, Trees, Vectors, etc) implement the Iterable interface, which adds the .Iterator() method, which returns an inner class Iterator (which is also an interface) object. An provides a standard way to access each item stored in that collection sequentially, with the ability to modify the value or remove it completely. Also, foreach loops work with anything implementing the Iterable interface, which allows you to design custom classes that work in a foreach loop. Here is a small code example in where I created a custom class, implemented the Iterable interface, coded the iterator() method that returns an inner class Iterator object, then in the main method use that class in a foreach loop:
+1
Gellert Varga
23 December 2021, 21:31
Lisa: Thank you very much for the explanatory example code, it was very informative!
By the way, after level 20, did you choose the multithreading section or Collections to progress?
Which one would you recommend? Does it make any importance which one I choose?
+1
Gellert Varga
23 December 2021, 21:32
Lupe: very interesting, thank you!
I would also ask, is the name of the part between lines 17 and 30: "method reference"? Or is that something else?
+1
Guadalupe Gagnon
23 December 2021, 23:37useful
It's an anonymous class. It would be the same as if I actually made an inner class and then returned an object of it. Java allows you to shorten it down like I did in the code above. The code below is if I made a class and then returned an object of that class:
Both of my examples are functionally identical +1
Gellert Varga
23 December 2021, 23:49
Thanks, Lupe!
And Christmas greetings from Hungary too!:)
+2
Lisa
24 December 2021, 09:31
@Lupe and @Gellert, merry christmas to you both.
Gellert, I went the multithreading way and it was quite challenging. Collections now is frustrating for me. The topics would be interesting but validation so limited that I don't enjoy it at this time. I have to motivate myself again soon to keep on learning.
In addition to Lupes last post... method references are something far more special. They are calls to implementations of functional interfaces. And a functional interface only has one method. Cause, like in lambdas, the method name itself is not important anymore, the 'implementation' must not implement the interface, it just needs to be parameter and return value compatible.
+2
Lisa
24 December 2021, 09:31useful
+2
Gellert Varga
24 December 2021, 21:45
Thank you Lisa, and Merry Christmas to you too!
- Thank you for this very good example program!
I don't claim to understand everything perfectly, but it was very expressive and useful for me in relation to the method reference and anonymous class.
(Unfortunately, lambda is still a very foreign topic for me. Rather let's not go into it...)
But I would like to ask what exactly does the code :: mean?
+1
Lisa
27 December 2021, 14:06useful
The double colon is the method reference operator. Cause you answered crisprs question and he used streams and a method reference I'll show you the difference on a similar example using the print method.
And don't worry. To understand this you need to first learn and really understand inner classes. The next hard part is to get anonymous classes. Then it's not that difficult anymore to learn lambdas and later method references.
(I hate the CG limit of 1000 chars when I want to write a book... that's the imports for the below class. I had to remove some comments... the Supplier interface is just to be able to generate a stream. You see that in the implementation I return random Integers between 100 and 999. The generated stream in the main method is limited to 5 elements and sorted. Finally I output the resulting numbers and do this as crispr did in the mentioned thread. He used a method reference and as you can see in the comments it is a short form of an object of the IntConsumer class. Such an object the forEach method requires. You either can implement that interface or use an anonymous class, a lambda or the method reference). In the end and once you're used to it you can just look ant the code and you know at once what's happening there, don't you?)
Oh, the imports
+2
Lisa
27 December 2021, 14:07useful
+1
Gellert Varga
27 December 2021, 21:39
I tried the program:)
But I feel a bit uncomfortable again, because you put a lot of effort into it, but unfortunately it's still quite complicated for me. But partially understood, and I can see sometime later it will be a good fun:)
However, I have always saved such codes for myself, and I am absolutely sure that both the code and the explanation will be very useful for a full understanding of the topic (sometime later.)
Line41 and Line36 versions worked well,
but when I tried line23 and line29 versions I got an Exception in both of cases:
IntegerGenerator.java:23: error: incompatible types: OutputInt cannot be converted to Consumer<? super Integer>
.forEach(new OutputInt());
IntegerGenerator.java:29: error: incompatible types: <anonymous IntConsumer> cannot be converted to Consumer<? super Integer>
.forEach(new IntConsumer()
What do I need to do to make them work?
0
Lisa
28 December 2021, 08:50
Ups, sorry, at first I generated the stream just using an IntStream and mapping the rands on the generated ints. So it was all truly Integers. Then I switched to the Supplier interface and that is parameterized and the IntConsumer had to change to a Consumer. You see that I have changed the OutputInt class to implement that Consumer (and to be the same as the inner class I didn't parameterize it - cause I don't know if it is possible to parameterize anonymous classes - have to look that up now).
And as already mentioned, you an not feel comfortable seeing, reading or using such code. First you'd need to learn more about inner and anonymous classes. The other variants aren't that hard anymore (but I do not know if CG offers lessons for that, up to my level at least not).
0