Im very new to programming and want to know if I can somehow get the object from a class where I already used new MyClass(); to use it in another class and that I don't need to use new MyClass(); again. Hope you get the point.
Some very simple example:
class MyFirstClass
{
Something st = new Something();
}
class Something()
{
// some code
}
class MySecondClass
{
// This is where I want to use the object from class Something()
// like
getObjectFromClass()
}
You can use Singleton pattern to achieve this
This is kickoff example of such object. It has a private constructor and public class method getInstance:
static methods, which have the static modifier in their declarations,
should be invoked with the class name, without the need for creating
an instance of the class
When we make a call to getInstance it checks if an object has been created already and will return an instance of already created objected, if it wasn't created it will create a new object and return it.
public class SingletonObject {
private static int instantiationCounter = 0; //we use this class variable to count how many times this object was instantiated
private static volatile SingletonObject instance;
private SingletonObject() {
instantiationCounter++;
}
public static SingletonObject getInstance() {
if (instance == null ) {
instance = new SingletonObject();
}
return instance;
}
public int getInstantiationCounter(){
return instantiationCounter;
}
}
To check how does this work you can use the following code:
public static void main(String[] args) {
SingletonObject object = SingletonObject.getInstance();
System.out.println("Object was instantiated: " + object.getInstantiationCounter() + " times.");
object = SingletonObject.getInstance();
System.out.println("Object was instantiated: " + object.getInstantiationCounter() + " times.");
object = SingletonObject.getInstance();
System.out.println("Object was instantiated: " + object.getInstantiationCounter() + " times.");
}
Since you have just started coding won't give you a term like reflection and all.. here is one of the simple way is have a public getter() method.
Consider this simple example
class Something {
private int a=10;
public int getA() {
return a;
}
}
Here is the First which has a public method which return the object that i created in this class for the Something Class
class MyFirstClass {
private Something st;
public MyFirstClass() {
this.st = new Something();
}
public Something getSt() {
return st;
}
}
Accessing it from another Class
class MySecondClass {
public static void main(String...strings ){
MyFirstClass my =new MyFirstClass();
System.out.println(my.getSt().getA());
}
}
Output: 10
If You wan't to verify
Inject this function in MyFirstClass
public void printHashcode(){
System.out.println(st);
}
and then print the hash codes from both methods in MySecondClass
class MySecondClass {
public static void main(String...strings ){
MyFirstClass my =new MyFirstClass();
System.out.println(my.getSt());
my.printHashcode();
}
}
You will see that indeed you are using the Object created in MyFirstClass in MySecondClass.
Because this will give you same hashcode output.
Output On my machine.
Something#2677622b
Something#2677622b
Instead of using the Singleton pattern, a better pattern to use is dependency injection. Essentially, you instantiate the class you want to share, and pass it in the constructor of every class that needs it.
public class MainClass {
public static void main(String[] args) {
SharedClass sharedClass = new SharedClass();
ClassA classA = new ClassA(sharedClass);
ClassB classB = new ClassB(sharedClass);
}
}
public class ClassA {
private SharedClass sharedClass;
public ClassA(SharedClass sharedClass) {
this.sharedClass = sharedClass;
}
}
public class ClassB {
private SharedClass sharedClass;
public ClassB(SharedClass sharedClass) {
this.sharedClass = sharedClass;
}
}
Singleton pattern lets you have single instance which is 'globally' accessible by other classes. This pattern will 'guarantee' that you have only one instance in memory. There are exceptions to one instance benefit, such as when deserializaing from file unless care is taken and readResolve is implemented.
Note that class Something right now has no state(fields), only behavior so it is safe to share between multiple threads. If Something had state, you would need to provide some kind of synchronization mechanism in multi thread environment.
Given such stateless Singleton, it would be better to replace it with class that contains only static methods. That is, unless you are implementing pattern such as Strategy which requires interface implementation, then it would be good idea to cache instance like bellow with Singleton pattern.
You should rework your Something class like this to achieve singleton:
public class Something {
private static final Something INSTANCE = new Something ();
private Something () {
// exists to defeat instantiation
}
public Something getInstance() {
return INSTANCE;
}
public void service() {
//...
}
public void anotherService() {
//..
}
}
If FirstClass and SecondClass are somehow related, you can extract that common object you're using to a super class, and that's the only scope in which you're planning to use this object.
public class SuperClass{
Something st = new Something();
public Something getObjectFromClass(){
return st;
}
}
public class MyFirstClass extends SuperClass{
getObjectFromClass();
}
public class MySecondClass extends SuperClass{
getObjectFromClass();
}
Otherwise, if you plan to use that instance somewhere else you should use a
Singleton object. The easiest way of doing this is:
enum Singleton
{
INSTANCE;
private final Something obj;
Singleton()
{
obj = new Something();
}
public Something getObject()
{
return obj;
}
}
You use it:
Singleton.INSTANCE.getObject();
Okay firstly you can use inheritance e.g.
class MyFirstClass
{
Something st = new Something();
}
class Something()
{
// some code
}
class MySecondClass extends myFirstClass
{
// This is where I want to use the object from class Something()
// like
MySecondClass obj = new MySecondClass();
obj.method(); //Method from myfirstclass accessible from second class object
}
Or if you dont want any objects and just the method you can implement interfaces e.g.
public interface MyFirstClass
{
//example method
public abstract void saying(); //no body required
Something st = new Something();
}
class Something()
{
// some code
}
class MySecondClass implements MyFirstClass //Have to implement methods
{
public void saying(){ //Method implemented from firstClass no obj
System.out.println("Hello World");
}
getObjectFromClass()
}
Related
What is the right / most popular way to utilize the Singleton Pattern.
Limit the no. of calls to getInstance(), preferably call it only once, and pass the object around to other classes during their instantiation?
class SingletonClass {
// Implementataion
}
class MainClass {
private SingletonClass singletonClassObject;
public MainClass() {
singletonClassObject = SingletonClass.getInstance();
new SomeClass(singletonClassObject).doSomething();
new SomeOtherClass(singletonClassObject).doSomethingElse();
}
}
class SomeClass {
private SingletonClass singletonClassObject;
public SomeClass(SingletonClass singletonClassObject) {
this.singletonClassObject = singletonClassObject;
}
public void doSomething() {
System.out.println(singletonClassObject.getStuff());
}
}
class SomeOtherClass {
private SingletonClass singletonClassObject;
public SomeOtherClass(SingletonClass singletonClassObject) {
this.singletonClassObject = singletonClassObject;
}
public void doSomethingElse() {
System.out.println(singletonClassObject.getStuff());
}
}
Don't pass the singleton object around. Rather call get the object reference in each class and save the reference as an instance variable and use it wherever required.
class SingletonClass {
// Implementataion
}
class MainClass {
public MainClass() {
new SomeClass().doSomething();
new SomeOtherClass().doSomethingElse();
}
}
class SomeClass {
private SingletonClass singletonClassObject;
public SomeClass() {
singletonClassObject = SingletonClass.getInstance();
}
public void doSomething() {
System.out.println(singletonClassObject.getStuff());
}
}
class SomeOtherClass {
private SingletonClass singletonClassObject;
public SomeOtherClass() {
singletonClassObject = SingletonClass.getInstance();
}
public void doSomethingElse() {
System.out.println(singletonClassObject.getStuff());
}
}
Don't even save the reference as an instance variable, rather use SingletonClass.getInstance() everywhere you need the object.
class SingletonClass {
// Implementataion
}
class MainClass {
public MainClass() {
new SomeClass().doSomething();
new SomeOtherClass().doSomethingElse();
}
}
class SomeClass {
public SomeClass() {
}
public void doSomething() {
System.out.println(SingletonClass.getInstance().getStuff());
}
}
class SomeOtherClass {
public SomeOtherClass() {
}
public void doSomethingElse() {
System.out.println(SingletonClass.getInstance().getStuff());
}
}
How do these approaches compare with each other w.r.t. better design, testability etc? Which is better and why?
If we assume for a moment that SingletonClass is not a singleton and we do not get an instance by calling static method we face another problem, how to link these classes together. This problem is solved by Dependency Injection and this concept is well described here:
Inversion of Control Containers and the Dependency Injection pattern
Unit Testing 101: Inversion Of Control
After reading above it should be easy to choose option .1 where all classes get in constructor references to required dependencies. You can even create an interface for a behaviour you need and implement it in SingletonClass. Now you see, that a fact that class implements Singleton pattern does not make it special and we should inject them like other classes. All benefits from using DI you can apply to your class.
Just compare it with .3 and you need to write a test where you need mock something. It would be more unpleasant task then in case of .1.
Look at it this way: you're questioning the compiler's ability to recognize that a static final reference can be compiled as an inline reference.
I would guess the compiler converts the getInstance() to an inline reference. I would be less confident that the compiler would recognize that you're intentionally creating extra work for yourself when you pass a reference by value, and that it would create an extra reference on the stack when you passed it around.
My guess is that getInstance() would be more efficient.
I can solve this problem using singleton pattern. But problem is I don't have control on other application which is going to call new MyClass(). Is there any way I can do in implicit constructor of MyClass?. Something like this.
class ClassName {
public ClassName() {
if( object exist for ClassName)
return that
else
create New ClassName object
}
}
Thanks in advance.
You can use a enum:
public enum ClassName {
INSTANCE;
}
Now, you have one instance and you don't have to worry about others instantiating your class.
Is there any way I can do in implicit constructor of MyClass?.
No, that can't be done in a constructor.
If you want to control construction, put in an explicit constructor and declare it private. You can call it from a static factory method, in the class.
This is probably what you want:
public class MySingletonClass {
private static MySingletonClass instance = null;
private MySingletonClass() { }
public static MySingletonClass getInstance() {
if (instance == null) {
instance = new MySingletonClass();
}
return instance;
}
// add your methods here.
}
This way nobody can call new MySingletonClass();. To get the one and only instance of the object you have to write:
MySingletonClass msc = MySingletonClass.getInstance();
or use it somehow like this for void methods:
MySingletonClass.getInstance().yourMethod();
or like this for Methods with a return type:
VariableType foo = MySingletonClass.getInstance().yourMethod(); // Must return VariableType
You would need something like this:
class ClassName {
private static ClassName INSTANCE;
private ClassName() {
//create ClassName object
}
public static ClassName getInstance(){
if (INSTANCE == null){
INSTANCE = new ClassName();
}
return INSTANCE;
}
}
Which is just a basic implementation of the singleton pattern.
If the class that constructs the object HAS to construct it using new, then you are kind of screwed. There is really no way to implement a singleton pattern in Java using only a public constructor.
Edit: You might be able to do something like this:
class ClassNameWrapper extends ClassName {
private final ClassName className;
public ClassNameWrapper(){
className = ClassName.getInstance();
}
//overload methods from ClassName
}
This way, every call to new ClassNameWrapper() will be using the same instance of ClassName.
Create a static variable in your class and hold your object instance there. Expose you class object through a getter method as below:
class ClassName {
private static ClassName myClass= null;
public ClassName getClassName() {
if(myClass == null){
ClassName.myClass = new ClassName();
}
return ClassName.myClass;
}
}
I have tree classes.
class MyObject{
public void DoSomething()
{
here I need to call method add from class base.
}
}
class base
{
protected final void add(){}
}
class extended extends base {
private MyObject pObject = new MyObject();
...
{
pObject.DoSomething();
}
}
I could have created class for each variation that extends class extended, but the type what I need to use becomes available only after class extended is already initiated.
How do I call base.add() from MyObject inner method?
You can do it in a couple of ways:
Have a reference of your extended class in MyObject class. When you instantiate MyObject variable in extended class, pass it the reference of extended.
Something like this:
class MyObject{
private base baseObj;
public MyObject(base baseObj){
this.baseObj = baseObj;
}
public void DoSomething()
{
//here I need to call method add from class base.
//use baseObj to call the methods
}
}
class base
{
protected final void add(){}
}
class extended extends base {
private MyObject pObject;
...
public extended(){
pObject = new MyObject(this);
}
{
pObject.DoSomething();
}
}
Declare the methods in base class static. This way you can call the methods without requiring an instance of the base class.
Something like this:
class MyObject{
public void DoSomething()
{
//here I need to call method add from class base.
//call like this
base.add();
}
}
class base
{
protected static final void add(){}
}
class extended extends base {
private MyObject pObject;
...
public extended(){
pObject = new MyObject(this);
}
{
pObject.DoSomething();
}
}
One more thing: This is off-topic, but you might want to read about Java Naming Conventions. Having class names start with lowercase is something that you wouldn't find in the naming conventions.
dummy code like this:
class MyObject{
public void DoSomething(Base base)
{
base.add();
}
}
class extended extends base {
private MyObject pObject = new MyObject();
...
{
pObject.DoSomething(this);
}
}
I have a parent class like
class A{
//Constructors only called by builder.
public static class builder{
//builder code.
}
}
Class B Extends ClassA{
//constrctor
}
Now if i do in my test
final classA dempClassA = new ClassB("parameters here");
how can i call the builder now..?
Sorry guys the builder is a class...My mistake.
If I understand well what you're trying to say, you have the following situation:
public class ClassA {
// Constructors only called by builder.
public static class Builder {
// builder code.
public static void hello() {
System.out.println("Hello");
}
public void hello1() {
System.out.println("Hello1");
}
}
}
And you access it this way:
class ClassB extends ClassA {
public static void main(String[] args) {
ClassA.Builder.hello();
ClassA.Builder builder = new Builder();
builder.hello1();
}
}
If you want to call that method from outside the A class then it shouldn't be private.
If you just want it to be part of the B creation process then you should do something like this:
class B extends A {
public B() {
super(); // invokes A's constructor
}
}
class A {
public A(){
// use builder() here
}
}
Make ClassA's builder method protected (rather than private), so they're visible to ClassB, then use an anonymous class to call it, like this:
ClassA tempClassA = new ClassB("parameters here") {
{
// This block is called during construction
builder();
}
};
Since the builder (is that a class btw? or is the return type missing?) is static, you'd call it like A.builder(). And for it to be visible, you shouldn't make it private :)
Edit: since it is a class, you have several possibilities:
if you need a new instance call new A.builder(...)
if builder provides static methods (in which case the question would be why this is a class) call A.builder.someStaticMethod(...)
I'm not sure if my question title describes my situation aptly, so my apologies if it doesn't! Anyway, let's say I have the following code snippet (visibility is as stated):
public class ChildClass extends ParentClass {
// more code
private void myMethod() {
MyClass mine = new MyClass() {
public void anotherMethod() {
// insert code to access a method in ParentClass
}
};
}
}
Is it possible for code within anotherMethod() to access a protected method found in ParentClass? If so, how can this be done?
I've tried something like...
(ParentClass.this).parentMethod();
...but obviously it doesn't work due to scope issues.
This compiles fine:
class MyClass {
}
class ParentClass {
protected void parentMethod() {
}
}
class ChildClass extends ParentClass {
private void myMethod() {
MyClass mine = new MyClass() {
public void anotherMethod() {
parentMethod(); // this works
}
};
}
}
A non-static inner class can access all methods of the enclosing class as if it were it's own methods:
public class Test {
public int getOne() {
return 1;
}
public class Inner {
public int getEnclosingOne() {
return getOne(); // this works...
}
}
}
A static inner class can not, as a static inner class is not bound to an instance of the parent class. That can only call static methods on the enclosing class.
As for methods when taking into account inheritance, an method in a non-static inner class can use all the methods of the enclosing (outer) class.
The interesting part is Test2.super.getOne() which indeed obtains getOne() from Test2.super, which is a Test. This is just like Test2 would access the method, namely using super though prefixed with Test2 to indicate you're accessing the namespace of the outer class.
public class Test2 extends Test {
public int getInnerOuterParentOne() {
Inner2 inner2 = new Inner2();
return inner2.getOuterParentOne();
}
public int getInnerOuterOne() {
Inner2 inner2 = new Inner2();
return inner2.getOuterOne();
}
public int getOne() {
return 2;
}
public class Inner2 {
public int getOuterOne() {
return getOne();
}
public int getOuterParentOne() {
return Test2.super.getOne();
}
}
public static void main(String[] args) {
Test2 test2 = new Test2();
System.out.println(test2.getInnerOuterOne()); // 2
System.out.println(test2.getInnerOuterParentOne()); // 1
}
}
There is no way to access "parent class method" in Java, irrelatively to visibility (except for super.parentMethod() in subclass's parentMethod()).
That is, if ChildClass overrides parentMethod(), there is no way to call ParentClass.parentMethod() (bypassing ChildClass.parentMethod()) from other methods of ChildClass.
However, if ChildClass doesn't override parentMethod(), that method is inherited by ChildClass, so that you can access it as a ChildClass's method, i.e. simply as parentMethod().