Object creation, variable initialization - java

Im reading through someone else´s code and theres this piece of code:
class Wrapper {
UnaryOperator<String> f;
}
Wrapper w = new Wrapper() { // line 3
{
f = s -> s.length() <= 1 ? s : f.apply(s.substring(1)) + s.substring(0, 1);
}
};
So if i understood it correctly, he creates a new Wrapper objecet and already initializes its variable f. I´m unfamiliar with the syntax from line 4 on, i only knew something like that from anonymous classes, but this isn´t one. Can you just initializes variables in between {} after you create a new Class()? Can you also do more than that, like override or define new methods? And why do you have to put {} in between each initialization?

It is an Instance Initialization Block. Read more in this question

Related

How to define a method with Integer parameter (path placeholding)?

Preface
I'd like to saying two things:
I don't know how to phrase this question in a few words. So I can't find what I'm looking for when searching (on stackoverflow). Essentially, I apologize if this is a duplicate.
I've only been programming Java consistently for a month or so. So I apologize if I asked an obvious question.
Question
I would like to have a method with a parameter that holds (path to) an integer.
How is such a method implemented in Java code?
Restrictions
The parameter should be generic.
So, when there are multiple of that integer variables, the correct one can be used as argument to the method, when it is called (at runtime).
My Idea as Pseudo-Code
Here's the idea of what I want (in pseudo-code). The idea basically consist of 3 parts:
the method with parameter
the variables holding integer values
the calls of the method with concrete values
(A) Method
.
Following is the definition of my method named hey with generic parameter named pathToAnyInteger of type genericPathToInt:
class main {
method hey(genericPathToInt pathToAnyInteger) {
System.out.println(pathToAnyInteger);
}
}
(B) Multiple Integer Variables
Following are the multiple integer variables (e.g. A and B; each holding an integer):
class A {
myInt = 2;
}
class B {
myInt = 8;
}
(C) Method-calls at runtime
Following is my main-method that gets executed when the program runs. So at runtime the (1) previously defined method hey is called using (2) each of the variables that are holding the different integer values:
class declare {
main() {
hey("hey " + A.myInt);
hey("hey " + B.myInt);
}
}
Expected output
//output
hey 2
hey 8
Personal Remark
Again, sorry if this is a duplicate, and sorry if this is a stupid question. If you need further clarification, I'd be willing to help. Any help is appreciated. And hey, if you're going to be unkind (mostly insults, but implied tone too) in your answer, don't answer, even if you have the solution. Your help isn't wanted. Thanks! :)
Java (since Java 8) contains elements of functional programing which allows for something similiar to what you are looking for. Your hey method could look like this:
void hey(Supplier<Integer> integerSupplier) {
System.out.printl("Hey" + integerSupplier.get());
}
This method declares a parameter that can be "a method call that will return an Integer".
You can call this method and pass it a so called lambda expression, like this:
hey(() -> myObject.getInt());
Or, in some cases, you can use a so called method referrence like :
Hey(myObject::getInt)
In this case both would mean "call the hey method and when it needs an integer, call getInt to retrieve it". The lambda expression would also allow you to reference a field directly, but having fields exposed is considered a bad practise.
If i understood your question correctly, you need to use inheritance to achive what you are looking for.
let's start with creating a hierarchy:
class SuperInteger {
int val;
//additional attributes that you would need.
public SuperInteger(int val) {
this.val = val;
}
public void printValue() {
System.out.println("The Value is :"+this.value);
}
}
class SubIntA extends SuperInteger {
//this inherits "val" and you can add additional unique attributes/behavior to it
public SubIntA(int val) {
super(val);
}
#override
public void printValue() {
System.out.println("A Value is :"+this.value);
}
}
class SubIntB extends SuperInteger {
//this inherits "val" and you can add additional unique attributes/behavior to it
public SubIntB(int val) {
super(val);
}
#override
public void printValue() {
System.out.println("B Value is :"+this.value);
}
}
Now you method Signature can be accepting and parameter of type SuperInteger and while calling the method, you can be passing SubIntA/SuperInteger/SubIntB because Java Implicitly Upcasts for you.
so:
public void testMethod(SuperInteger abc) {
a.val = 3;
a.printValue();
}
can be called from main using:
public static void main(String args[]){
testMethod(new SubIntA(0));
testMethod(new SubIntB(1));
testMethod(new SuperInteger(2));
}
getting an Output like:
A Value is :3
B Value is :3
The Value is :3
Integers in Java are primitive types, which are passed by value. So you don't really pass the "path" to the integer, you pass the actual value. Objects, on the other hand, are passed by reference.
Your pseudo-code would work in Java with a few modifications. The code assumes all classes are in the same package, otherwise you would need to make everything public (or another access modifier depending on the use case).
// First letter of a class name should be uppercase
class MainClass {
// the method takes one parameter of type integer, who we will call inputInteger
// (method-scoped only)
static void hey(int inputInteger) {
System.out.println("hey " + inputInteger);
}
}
class A {
// instance variable
int myInt = 2;
}
class B {
// instance variable
int myInt = 8;
}
class Declare {
public static void main() {
// Instantiate instances of A and B classes
A aObject = new A();
B bObject = new B();
// call the static method
MainClass.hey(aObject.myInt);
MainClass.hey(bObject.myInt);
}
}
//output
hey 2
hey 8
This code first defines the class MainClass, which contains your method hey. I made the method static in order to be able to just call it as MainClass.hey(). If it was not static, you would need to instantiate a MainClass object in the Declare class and then call the method on that object. For example:
...
MainClass mainClassObject = new MainClass();
mainClassObject.hey(aObject.myInt);
...

Why can't I instantiate outside any method in java?

Please ignore my arrogance......learning java these days, i came across this perfectly same question for my problem : Why can't I instantiate and create Object without main method? (Stack Overflow Error)
Expecting a possible downvote too...but please go through my question once!!!!
Code that i was trying :
public class Arrayprg{
Arrayprg ag = new Arrayprg(); //ignore this for a while and go thru code please
public static void main(String []args){
System.out.println("Hello Array");
new Arrayprg().declarearray();
}
public void declarearray()
{
int[] arr;
arr = new int[11];
new Arrayprg().assignarr(arr);
}
public void assignarr(int arr[])
{
int i;
for(i = 0; i < 11; i++)
{
arr[i] = i;
}
new Arrayprg().printarr(arr);
}
public void printarr(int arr[])
{
int i;
for(i = 0; i < 11; i++)
{
System.out.println(arr[i]);
}
}
}
Thinking logically, going through the code you'll see lots of new arrayprg()....what i thought of was to instantiate outside of methods and calling all methods through it there after, but i guess it is not allowed in java.
Whats causing my Problem
Going by the solution in quoted question, as it explain that below thing happens :
Create new instance of Arrayprg
-> ag = Create new instance of Arrayprg
-> ag = Create new instance of Arrayprg
-> ag = Create new instance of Arrayprg
Explanation given in that question
.....it is initialized whenever an instance of the class is instantiated. This will never terminate until you run out of memory and get the stack overflow. Run it with a debugger for a clearer view.
My Question
so i have Arrayprg ag = new Arrayprg(); in my program which is creating a loop every-time i create an instance but why is this called when i am calling the functions through new Arrayprg().
What i mean is that when i am calling the function through new Arrayprg() inside the methods why is Arrayprg ag = new Arrayprg(); getting called and creating the loop of error for Stackoverflow?????
This will cause a StackOverflowError.
The line you tell us to ignore, interestingly, is the culprit. When you instantiate a new Arrayprg then any object initializers are called, including new Arrayprg() which will then recursively try to keep invoking constructors without end. Remove that line, or put it in a static initializer. Better yet, just don't create that Arrayprg outside the main method as your Arrayprg does not need an instance of Arrayprg itself,
I would be more clear but I don't know what you're trying to achieve.
Solution : Change this line:
Arrayprg = new Arrayprg(); //ignore this for a while and go thru code please
to:
static Arrayprg a = new Arrayprg();
And you will no longer get your infinite recursion problem as now it will only create one instance of it shared between all instances - rather than each instance immediately creating a new one.
The Explanation
As part of constructing an Object in Java all member variable initializers, initializer code blocks, etc are all called as well as the constructor itself.
So in order to create a new Arrayprg one of the things it does is look for member variables that need initializing and initialize them.
In this case it finds Arrayprg a = new Arrayprg();, so in order to initalise the field a, it tries to create a new Arrayprg().
But that new Arrayprg() goes through the exact same process again, and again, and again, etc.
There are a number of ways to fix this - including:
Pass in the Arrayprg as a parameter to the constructor - so a new one doesn't need to be created.
Make the Arrayprg static - so only a single one needs to be created once rather than creating a new one each time
Lazy initaliziation on the Arrayprg so that you only create it the first time you try and access it rather than when the parent Arrayprg is created.
Why it doesn't happen in a method call:
The important thing that causes the recursion here is that the call happen during the creation of a new object. If trying to create a new object involves creating another copy of the same object then you will end up with infinite recursion which will then cause the failure.
So you can create a new object anywhere you like - so long as it is not inside the creation of itself.
class A {
A a = new A(); // Recursion
}
class A {
A() {
A a = new A(); // Recursion
}
}
class A {
A getNewA() {
return new A();
// This is fine as it doesn't happen during creation of an A
}
}
class A {
A() {
getNewA();
// Recursion as calling getNewA creates a new A, which calls getNewA, which....
}
A getNewA() {
return new A();
// This is fine on its own but is broken if called from the constructor
}
}
class B {
A a = new A();
// This is fine as B is not A, so you can create a new A within B.
}
Let's step through this visually.
Arrayprg = new Arrayprg();
So what do you need to create an object of type Arrayprg? Well you need to create it's fields.
Arrayprg = new Arrayprg();
And once again, you're telling the JVM to give you another Arrayprg object. By definition, this means making another Arrayprg object.
This is giving you a StackOverflowException.
Solution?
You shouldn't really be nesting types like this. It's pointless. You're inside the class already, so use it's methods.
public void declarearray()
{
int[] arr;
arr = new int[11];
assignarr(arr);
}
Follow this pattern, and you'll eliminate the need for the Arrayprg field.
Every time you create an instance of Arrayprg, you call this line: Arrayprg = new Arrayprg();, this means every time you create one, it creates another and another and another etc. You can instantiate objects there, but instantiating another object of the same type causes your infinite loop.
Also, in your methods (declareArr, assignArr etc) you can remove the 'new Arrayprg().' and just call the functions on the existing object.
In a class you can create objects outside any method, object cannot be of the same class.
It is meaningless. Take it as a rule.

Can someone explain to me why I'm having this error?

Good day,
I have a question on which in my code, one declaration is having an error outside a function.
The snippet is:
public class Gold {
Block[][] block = new Block[4][4];
this.block[1][4] = new Block(); //1
public void populate() {
this.block[1][4] = new Block();//2
}
}
The code this.block[1][4] = new Block(); number 2 is not having an error. However, the first code which is not inside the function is showing the error:
Illegal start type
Cannot find symbol
']' expected
invalid method declaration, return type required.
I just want to understand why this is hapenning and what I am missing.
Thanks
There is no element with index 4. The last element has index 3.
You can not initialize variables directly as you did above in case 1, You can initialize block[][] in constructor like :
public Gold(){
this.block[1][3] = new Block();
}
OR in block like :
Block[][] block = new Block[4][4];
{
this.block[1][3] = new Block();
}
You have a statement which must be in a block of code.
Try
public class Gold {
Block[][] block = new Block[4][4];
{ // initializer block
this.block[1][3] = new Block(); //1
}
You have two problems here, You need to initialize any object in a scope. Either you have to call the Number 1 line in a constructor or in a function or with in a block (enclosed with in{and}). Here you need to know difference between static block and non-static blocks.
Other problem you have is this.block[1][4] = new Block(); will throw an ArrayIndexOutofBounds exception as the length of the array is 4 and you are trying to insert and object at 5th place.
I think that you should place your code in constructor:
public Gold(){
this.block[1][4] = new Block();
}
In java class you can define variables or methods (including constructors) but can not use plain code in it.
this.block[1][4] = new Block(); //1
is an expression not a field initialization. It cannot be outside of a method body.
You need to wrap your code in a method, not in the class body. If its part of the initialization of the Gold class put it inside its constructor like:
public class Gold {
Block[][] block = new Block[4][4];
public Gold() {
this.block[1][4] = new Block();
}
}
The class body allows only variable declaration and instantiations, but not standard operations like changing an object's (your array) value.
EDIT: as other pointed out, the index 4 does not exist in an array of size 4, only indices from 0 to 3 can be accessed.
The code this.block[1][4] = new Block() is compiled but will fail on runtime: your array has 4 elements while index in java and all C-like languages starts from 0, so the max value of 4-elements long array is 3.
And you cannot write code outside methods in java, so if you try this you get compilation error.
This sentence
this.block[1][4] = new Block(); //1
cannot go outside a method or Initialisation block. If you want to initialize the array you have to do it on the declaration or inside a method (constructor could be a good place) or you have to use a Initialisation block.
Also check the array bounds. In Java arrays have 0 based indexes.

Difference between {} and {{}} initialization in Java

public class A{
}
A a = new A(){{
final int x = 1; // IT HAS TO BE FINAL HERE. WHY?
}};
A aa = new A(){
int x = 1; // THIS NEED NOT BE FINAL. WHY?
final int y = 1; // STILL FINAL IS ALLOWED HERE. WHY?
public int getX(){
return x;
}
};
Can somebody please answer the questions mentioned inside the snippet?
Thanks
The outer set of {} declares an anonymous subclass
The inner set declares an initialization block within that subclass.
With the following example, it becomes easier to understand what's going on:
List<String> strings = new ArrayList<String>() {{
add("string");
add("another string");
}};
You basically say: I want a subclass of List, which calls method add at initialization.
It's similar to:
List<String> strings = new ArrayList<String>();
strings.add("string");
strings.add("another string");
A a = new A(){{
final int x = 1; // IT HAS TO BE FINAL HERE. WHY?
It needn't.
The difference between the two is that in the first case, you're writing the code used to initialize each object in the double braces. That x is its local variable (doesn't have anything to do with objects of class A).
In the second case, you're defining the classes body. x would be its member variable. If it were static, its class variable. If final a (basically) constant.
I wonder, why would you want to use the first version of the code (the one with {{}}). The x variable declared inside it's not useful at all, it's local only to the block scope in which it was defined, and being inside an anonymous class, you won't be able to reference it anywhere in the code.
And anyway, the first version of x declaration does not need to be final, it compiles just as fine, with or without final.
In your first example the inner braces create something called an instance initializer. It's an obscure way to initialize variables and call instance methods when an object is constructed. So the first example creates an anonymous subclass of A and creates a local variable within the scope of the initializer. It doesn't have to be final.
In the second example you're creating an anonymous subclass of A but not creating an instance initializer, the variables you create are instance variables of the anonymous subclass.
The first instance A a = new A(){{... has an initialisation block inside the declaration. Another way of writing it would be like this:
A a = new A()
{
{
final int x = 1; // This is inside an initialisation block
}
};
Changing the formatting makes it a bit more obvious.

Java Syntactic Sugar

I ran into this block of code today, and I don't know how it works. I know how to make anonymous classes, but I'm used to seeing a method signature and not just a pair of braces. Is the code between those braces put into a static block? Does it go into the constructor? Or is it something else altogether?
conext.checking(new Expectations() {
{ // <- what does this pair of braces do?
oneOf(alarm).getAttackAlarm(null);
}
});
It's an instance initializer that calls the code within the context of the created object.
This is equivalent to
Expectations exp = new Expectations();
exp.oneOf(alarm).getAttackAlarm(null);
conext.checking(exp)
Whoever wrote it might have thought he was being more efficient by not declaring a variable (not true) or that it was cleaner code (I disagree).
The primary place that these initializers are useful like this is when instantiating maps, ie:
Map map = new HashMap() {{
put("key1", "value1");
put("key2", "value2");
}};
which I think actually is slightly more readable.
It is an initializer block, but not necessarily a static initializer block. It is effectively a constructor for an anonymous inner class. You will typically see this "double-brace initialization" pattern to conveniently create and populate collections:
private final Collection<Integer> FIXED_COLLECTION = Collections.unmodifiableCollection(new HashSet<Integer>()
{ // first set of braces declares anonymous inner class
{ add(1); add(2); add(3); } // second set is initializer block
});
It's an instance initialiser (not a static initialiser).
Consider the definition of a class
public class Foo {
private int i = getDefaultValue();
private static int getDefaultValue() {
return 5;
}
}
The call to getDefaultValue() that initalises i is essentially a code block that runs each time an instance of Foo is constructed. The notation extends that function to allow more complex initialisation. E.g.
public class Foo {
private int i;
{
int z = 4 + 5;
i = z + getDefaultValue();
}
private static int getDefaultValue() {
return 5;
}
}
The manner with which it is used in JMock is a trick to give expectations the look of a closure construct.
What's happening ? The outer braces create a new anonymous class derived from Exception. The inner braces define an initialiser and sets the oneOf() etc.
Why do this ? It's a one-liner trick for constructing and initialising an instance of a class. e. you sometimes see something like this:
new HashSet<String>(){{ add("one"); add("two"); }}
to initialise the contents of a collection.
Downsides ? Because you're creating an anonymous class within the containing class, that anonymous class contains a this reference to the outer class implicitly. Not normally a problem, but it can cause issues if (say) you want to serialise a class that you've constructed like this.
It's an initializer block. I can't tell what it does without looking at the rest of the code.
The trick is to imagine "new Expectation()" replaced with "class Something extends Expectation".
Anynoymous inner classes don't have a constructor, so you can define a an instance initilizer like this i.e. the inner set of braces are the instance initializers.
new Expectations() {
{
oneOf(alarm).getAttackAlarm(null);
}
}
The primary motivation behind this, I believe, is to create a new name space, in which names defined in Expection can be referenced more easily.
For example, suppose java.lang.Math is not final,
new Math()
{{
double x = sin(23.65);
double y = log(x);
...
}};
It's almost as if we have something like
with names from Math
{
double x = sin(23.65);
double y = log(x);
...
}

Categories