Referencing static object created in one class throughout entire application - java

I have a java application that creates two static objects in a base class, these objects needs to references throughout classes in the program.
public class Baseclass{
public static ClassA A = new ClassA();
public static ClassB B = new Classb();
...
...
...
}
These objects are referenced in the other classes as a local private variables.
public class ClassA{
private ClassB b = Baseclass.B;
However, both object require each other to function and if I creates a new instance of one of the objects before the other is created, the local variable in the "upper" classes is set to null. Is there any concepts in Java that would reference the actual object (like a pointer) to the object as a variable instead of making a copy of the object?

However, both object require each other to function and if I creates a new instance of one of the objects before the other is created, the local variable in the "upper" classes is set to null.
I think the answer you are looking for is a "singleton pattern". This is where you create just one instance of a class for use in other places. Here's a good link to read. Here's the wikipedia page on it with some java examples.
So your code would look something like this:
public class A {
private final static A instance = new A();
/* private constructor forces you to use the getInstance() method below */
private A() {}
public static A getInstance() {
return instance;
}
}
Then wherever you want to get an instance of A you would do something like:
public class B {
private final A classA = ClassA.getInstance();
...
}
There is no reason why A could not also have an instance of B and call B's methods in its own methods. What you cannot do with this cross dependency is call any of the other's methods in the constructor.
In general, by the way, these patterns should be used sparingly. A better way to accomplish this is through dependency injection instead of global references. Cross injection is possible but again, it should be used sparingly. A better solution would be to refactor the classes to have linear dependencies.
Is there any concepts in Java that would reference the actual object (like a pointer) to the object as a variable instead of making a copy of the object?
Java is pass by value but the value of any Object is the reference to the object (similar to pointers in C although they are not a memory address). So if you have an instance of A and assign it to another field, that field will be the same value and will be referencing the same instance of A.
// instantiate a new instance of A
A a1 = new A();
// assign the reference to A to another variable
a2 = a1;
// they are equivalent and both reference the same object
if (a1 == a2) ...

Is there any concepts in Java that would reference the actual object (like a pointer) to the object as a variable instead of making a copy of the object?
Actually, Java has only references. A variable can't contain an object, so no worries there.
Also, instead of doing
private ClassB b = Baseclass.B;
I'd suggest you consider doing a static import:
import static some.package.Baseclass.*;

When you make a reference in Java you are actually making a copy of a reference. You aren't copying Baseclass.B in your example. You're copying a reference to Baseclass.B.
In the example code you have provided, b is going to be null until Baseclass.B is defined. If you need to do an operation on b, you can't do it in the declaration of ClassA. You need to do it in a method that is called after object a has been created.

This is a classic application for a singleton.
For each one:
Make the constructor private.
Add a private static member of the class's own type to hold the
singleton.
Add a "getThe()" method which initializes the above member if it's not already set.
See wikipedia:Singleton pattern.
Make the constructor of A construct B also, by doing a getThe() on it.
Also, don't use public fields in Baseclass; instead use public getter methods. Don't keep a separate B variable; instead, ask the A singleton for it.

Is there any concepts in Java that would reference the actual object
(like a pointer) to the object as a variable instead of making a copy
of the object?
When you do this:
private ClassB b = Baseclass.B;
Really you are ponting at the same object a it's because the "b" variable is named Reference Variable.
About your question, my recomendation is do something like this:
First encapsule the reference:
public class ClassA{
private ClassB b;
public void setB(ClassB b) {
this.b = b;
}
public ClassB getB(ClassB b) {
return this.b;
}
}
Second use an static block for init the variables:
public class Baseclass{
public static ClassA A = new ClassA();
public static ClassB B = new Classb();
static {
A.setB(B);
B.setA(A);
}
}

Related

What happens to variables/objects in inner classes of function objects?

I have a function multi2 which returns inner class Inner as an Object.
What happens to a - where is it saved and how can I access it?
public class C {
private static Object multi2(final int a) {
class Inner {
public int hashCode() {
return 2*a;
}
}
return new Inner(); // What happens to a?
// Who allocates a?
// Can I Access a?
}
public static void main(String[] args) {
Object o = multi2(6);
System.out.println("o.hashCode() = " + o.hashCode());
o = multi2(4);
System.out.println("o.hashCode() = " + o.hashCode());
}
}
What happens at the implementation level is that a copy of the value of a is saved in a synthetic instance variable declared in the compiled version of the C.Inner class.
The value of a is passed to the compiled Inner constructor via an extra parameter.
The C.Inner.hashCode method uses the value of the synthetic variable. Accessing a in the source code of Inner.hashCode is transformed into accessing the corresponding synthetic variable in the compiled code.
The variable in the outer scope must be final1. The synthetic variable must be final2 in the Inner class. This maintains the illusion that (potentially) multiple instances of the Inner class are seeing the same a variable. (They aren't, but since the variable(s) can't be changed, it is not possible for the code of the inner class to tell the difference.)
If you use javap to look at the bytecodes for the compiled example, you will see the mechanisms used to implement this in the outer and the inner classes.
1 - or effectively final from Java 8 onwards.
2 - If a could be mutated by an Inner method, then two Inner instances with the same outer class need to share a mutable variable whose lifetime is (now) longer than the stackframe for a multi2 call. That entails somehow turning a from stack variable into something that lives on the heap. It would be expensive and complicated.
You have defined the class Inner inside the function so the scope of the class will be
restricted with in the method. And your function is static so it will be live as long as the class definition is loaded. You have override the hashCode function inside the InnerClass so every time you are calling the multi2(param) you are creating the hashCode for the instance of InnerClass and returning the instance of the InnerClass.
So as for you questions, please correct me if i am wrong.
What happens to a ?
a is with in the scope of your static method, so it will be live as long as the class definition is loaded.
Who allocates a?
scope of a is restricted inside the static method and static method does not require instance to access it but as for the static method/variable allocation, i think it depends on JVM.
Can I Access a?
No you cannot access a from outside you static method, it is restricted with in your static method.
Since the "a" is a local parameter, you could use a different approach to read the "a" value:
public class C {
public static Object multi2(final int a) {
return new Inner(a);
}
public static void main(String[] args) {
Object o = multi2(6);
System.out.println("o.hashCode() = " + o.hashCode());
System.out.println("o.getA() = " + ((Inner) o).getA());
o = multi2(4);
System.out.println("o.hashCode() = " + o.hashCode());
System.out.println("o.getA() = " + ((Inner) o).getA());
}
}
class Inner{
public int valueA;
public Inner(int a)
{
valueA = a;
}
public int getA() {
return valueA;
}
public int hashCode() {
return 2*valueA;
}
}
I wanted to know what was actually happening, so I compiled your code and looked at the bytecode output.
Basically what happens is the compiler adds in a constructor to your class 'Inner'. It also adds a single parameter to that constructor which takes 'a'. If your multi2() method was NOT static then there would probably also be a parameter to take 'this' where 'this' is the instance of 'C' that multi2() is executing on. BUT since we're in static context, there is no 'this'.
The compiler adds a private final field to your class 'Inner' and sets that private field using the value passed via the constructor. The compiler also converts
new Inner()
into
new Inner(a)
Hashcode then accesses the private field containing the value for a.
If 'a' was an object instead of a primitive, then it would be the same way, but a reference would be passed through instead of an actual number value.
How do you access this variable? Well you access it with reflections, but there are many problems:
1) You don't know the name of the field made by the compiler, so you can only get the name by looking at the bytecode. Don't trust decompilers as they might change the name. You gotta look at the bytecode yourself to find out.
2) The compiler probably marks the field as final, which means even if you can get reflections to access the field for you, you won't be able to update it.
3) It is entirely up to the compiler to figure out field names. Field names could change between builds depending on the compiler and it's mood.
Inner is a so called local class. a is a parameter passed to the method multi2 and accessable within that scope. Outside of that method, you cannot access a.

What is the exact meaning of instantiate in JAVA

I'am a newbie in JAVA and this came across this word called.
"A class i.e. created inside a method is called local inner class in java. If you want to invoke the methods of local inner class, you must instantiate this class inside the method".
The word in bold.
Can anyone please help me out with this one.I know it's embarrassing and i should've researched more but I just cannot understand.
Thanks.
First of all Declaring mean:
ClassName obj;
Simple meaning of instantiate is creating an object from class.
ClassName obj = new ClassName();
What is a object?
An instance of a class. From one class we can create many instances.
They are the basic runtime entities in in our program.
They may also represent user-defined data types such as lists and
vectors.
Any programming problem is analyzed in terms of objects and nature of
communication between them.
As a example:
//Define a reference(a variable) which can hold a `Person` obect.
Person p;
//Create a Person object(instantiate).
//new - use to allocate memory space for the new object
p = new Person();
What is a nested class?
A class that defined inside a class is called nested class. There 2 categories of nested classes.
inner classes
local classes
annonymous classes
Inner class:
Inner class can only be accessed by the outer class. Not by any other
class.
Inner class is a member of outer class.
Outer class can access inner class without importing.
Inner class can access any attribute or a method belong to outer
directly.
Outer class cannot access directly to a inner class.
Example for a inner class:
class Outer{
int i = 10;
void main(){
//instantiate inner class.
Inner in = new Inner();
in.show();
}
class Inner{
void show(){
System.out.print(i);
}
}
}
What is a local class?
Which are classes that are defined in a block.
Example:
public class{
int i = 10;
public main(){
class A{
void show(){
System.out.println(i);
}
}
//inside the method instantiate local class.
A obj = new obj();
obj.show();
}
//outside the main() -block(method)
//inside another method instantiate local class.
public test(){
A obj = new A();
obj.show();
}
}
To instantiate a class means to create an instance of the class. In other words, if you have a class like this:
public class Dog {
public void bark() {
System.out.println("woof");
}
}
You would instantiate it like this:
Dog myDog = new Dog();
Instantiating is when you use the new keyword to actually create an object of your class.
Instantiate == create an instance == create an object of a class.
Instantiate is creating an instance of a class. I reckon this is not helpful without knowing what an instance is.
Let's say you have a class definition like:
public class Person
{
private String name;
public Person(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
}
You make an instance of this class my calling its constructor and using the keyword new:
Person p = new Person("Hugh Laurie");
An instance of a class is a place in memory that contains the state (e.g., Person::name) of a given object which used as a template a class definition.
I want to further expand upon:
If you want to invoke the methods of local inner class you must instantiate this class
What this means is that, you need to have instantiated that class in order to use the above's example getName() method. After all, it is trying to access the state (name) of a given object in memory; without that object, there is no state.
Instantiate in Java means to call a constructor of a Class which creates an an instance or object, of the type of that Class. Instantiation allocates the initial memory for the object and returns a reference. An instance is required by non-static methods as they may operate on the non-static fields created by the constructor.
Static methods don't need an instance and should not be stateful, i.e. should not rely on changing data. They are essentially free functions that are associated with the type and not a particular instance. When you want to work with changing data, encapsulating that data as member fields that are operated on by instance methods is the way to go.
For example, a Car class might have static numbeOfWheels() that always returns 4, but an instance numberOfFlatTires() that might return 0-4 depending on the state of that particular Car.
Inner classes are no different and the only difference between a static and non-static inner class is that the non-static can use the parent instance's members. This can be used to reduce complexity. You might have a looping operation that has a common parameter for the list and an individual parameter for the items. You could use a non-static inner class to encapsulate the operations on the item while referring to the common parameter in the parent class.
Enums are special in that each value is a single instance of a single type that all extend from a common abstract base class defined in the Enum class body. The Enum value is instantiated the first time it's used, but there will only ever be one instance per value.
when you create an instance of a class or simply called as an object
for ex: Bike abc = new Bike();
as soon as you create this object using the new keyword, a new block of memory is created and object "abc" will now be pointing to that new block of memory, this is called as instantiation in java.
create an instance of the class by using "new" word
for example Car car = new Car();

How to use a Get method in java

A ton of questions have been asked on how to create getter and setter methods in java. But i have yet to see one that actually tells me how to use it.
Say i have Private int i = 1; in class A and i want to access it in class B.
I would first create a get method in class A called getIntI(); which would return the value of i.
Then in class B if i wanted to create an if statement that would need the value of i how would I get int i's value. The following is my try and calling the get method which does not work.
if(getIntI == 1)
{System.out.print.ln("int i is one");}
It is probably a really stupid question but i cant find an answer for it elsewhere.
In class A:
public int getIntI(){
return i;
}
Note: Now since your variable is single character named (just I), getter method is named getIntI since the name getI makes lesser sense. But generally, getter methods are something like get+VariableName and do not involve mentioning type. For example if I had a variable called int count, my method would be named getCount instead of getIntCount. Thats the general convention.
Also, naming variables in single char formats (like x, y etc) is discouraged because it may create confusion and management difficulty in complex programs. Though in very small programs they are fine.
Moving back to topic, if you want to access method getIntI() in class B, you will either have to inherit class A or create an object of class A reference to its method.
For class B:
Creating object
A obj = new A();
if(obj.getIntI() == 1)
// Do stuff
Inheriting class A:
public class B extends A{
... // Your stuff
if(getIntI() == 1)
// Do stuff
... // Your stuff
}
Of course there are other ways but these are simpler ones.
if class B extends class A then do only this changes,
if(getIntI() == 1)
If above inheritance was not there then do this,
if(new A().getIntI() == 1)
The problem is that you need to create a object derived from class A before you can access its variables/methods using
A a = new A();
where "a" is the name of the object. Then you can access the getter method by calling a.getIntI. You can also declare the int variable as static so that you wouldn't have to instantiate any objects. An example of class A with the static variable and getter method would be:
public class A {
private static int i = 1;
public static int getIntI() {
return i;
}
}
With this, you can call the getter method with A.getIntI().
First, if you want to access one of A's non-static methods (in this case, getIntI), you need an instance of A, or you can just declare it static.
Secondly, A method call needs a parameter list, even an empty one is needed. getIntI does not need any parameters, so you should add () at the end.
Now, you can get an instance of A somewhere and call it aObj. Andd then you can use it in the if statement:
if (aObj.getIntI == 1)
And remember to add ()!
if (aObj.getIntI() == 1)
Alternatively, you can declare i in A as static. There are two main differences between a static and a non-static variable.
You don't need an instance of the declaring class to access the static variable.
Unlike non-static variables, there is only one static variable. If you have a non-static variable i, you can create lots of instances of A and each instance will have its own i
Now let's see this in action, declare i as static:
public class A {
private static int i = 1;
public static int getIntI () { return i; }
}
Note how both i and getIntI are declared static.
Then you can use in a if statement like this:
if (A.getIntI() == 1)
Note how I use the class name A to access the method, not an instance of A.

Are static class members static in Java?

In the below code, are b and show inherently static?
public class A {
public static class B {
private int b = 0;
public void show() {
System.out.println(b);
}
}
}
No they aren't static. You need to create an instance of B to access them.
The static keyword in your code example means that instances of B can be created without an instance of A.
If B was not static:
Instances would have an implicit reference to an instance of A.
The only way to create them would be to use new B() inside class A, or using syntax like new A().new B().
Methods in B can refer to A.this (the implicit reference to an instance of A).
Methods in B can refer to A.this.someField (using that implicit reference).
Methods in B can call instance (non-static) methods in A.
However, because B is static:
Instances do not have a reference to an instance of A - you don't need an A to create a B.
Instances can be created using new A.B() (or just new B() from within in class A)
Methods in B cannot refer to A.this.
Methods in B cannot access fields in A (unless passed in as a parameter).
Methods in B cannot call instance (non-static) methods in A.
They are not static. They are instance fields in B.
Meaning you need to have an instance of B to get/set them.
B is static in A but that does not make those fields of B static.
You can create many instances of B without any reference to A.
So B is static class in A but the same is not true for B's instance fields.
The static keyword has two meanings that are actually quite different and that can be confusing.
Static on a variable/method means that it exists at the class level, not the instance level. This means that you only have one copy of that variable/method no matter how many instances of the class you create.
Static on an inner class though just means that the class does not depend upon its outer class. In your example you can create a new B() without having an A. If you didn't have the static keyword on the class you could not create a new B() unless it was within an instance of A.
B is a static inner class of A.
Need to instantiate B.
A.B innerObject = new A.B();
innerObject.show();
The identifier static has a specific purpose here that many people don't immediately grasp. I'm going to take your code and change it a bit.
public class A {
private int a;
public A(int a) {
this.a = a;
}
public class B {
public void show() {
System.out.println(a);
}
}
}
Now, what's happening in class B? Because B is a non-static class, it has access to other non-static members in class A. Essentially, it states that every class A object has their own flavor of class B objects, even thought they are functionally the same. For us to get that same behavior if B was a static class:
public class A {
private int a;
public A(int a) {
this.a = a;
}
public int getA() { return a; }
public static class B {
public void show(A a) {
System.out.println(a.getA());
}
}
}
Here, this implies that the flavor of B objects doesn't change depending on which A object created it. The B class is static so that it cannot access non-static members of the A class object that created it and must access those members explicitly from whichever A object it wants to interact with.
In the previous implementation, a B object would seamlessly access fields and non-static methods of the A object that created it.
These are two different behaviors and often it's clear exactly which one fits your objective.

is possible to access to the field of a A class instance from another B class instance created in the A class instance

I'm wondering whether is possible to access to the information contained in a field of a class from another class that's been created inside of the first one. I put a snippit of Java code for showing I want to do.
public class A {
public String c = new String();
B b;
...
...
...
public void doSomething() {
b = new B();
}
}
public class B {
...
...
...
public void retrieveInformationFromA() {
// I need to retrieve the field "c" of A instance that's
// created the B instance
}
}
NOTE: Due restrictions of the current design of this code I can't to create a constructor in B that includes a parameter for field "c" of A class. Due to legacy code, I have to avoid changing the existing code as much as possible.
I appreciated any help!!
UPDATE: I've corrected the code, I forgot to add the public modifier to the field "c" in A.
Since you did not specify any visibility (public, private, protected) to field 'c' it is implied to be "package protected" i.e. all classes in the same package as class A can access that field directly.
So, if your classes A and B are in the same package, you can access field 'c' directly from class B.
If they are not in the same package, you can not access it normally, but need to use reflection (and this should be the absolute last resort): How do I read a private field in Java?
Edit: But you still have to pass a reference to the instance of class A to the class B. If you can not change class B you are completely out of luck.
Declare the string as static
public class A {
static String c = new String();
and then access it in B like
public void retrieveInformationFromA() {
String info = A.c;
// I need to retrieve the field "c" of A instance that's
// created the B instance
}
If c needs to be different or non static
public void retrieveInformationFromA() {
A obj = new A();
String info = obj.c;
// I need to retrieve the field "c" of A instance that's
// created the B instance
}
In my experience that is not possible.
The called instance b has no knowledge of the world surrounding it apart from what you hand down.
You may include a setter with class B to hand 'c' down if you do not want or cannot declare c as static.
Another method could be an intermediate "InfoBase" class, which contains fields one or more different classes will need.
You cant retrieve the field "c" of A because its private member of class A. To access field in this case use getter setters(for c in this case) or make it public ( a really bad approach). Happy Coding:)
You could do something like this
// In class A
public void doSomething() {
b = new B();
b.retrieveInformationFromA(this);
}
...
// In class B
public void retrieveInformationFromA(A a) {
String c = a.c; // This way you can get it
// I need to retrieve the field "c" of A instance that's
// created the B instance
}

Categories

Resources