I am starting in java, so please bear with me if this sounds stupid.
I am trying the below code:
First.java
class First {
public static void main( String[] args ) {
First f = new First();
f.print();
}
private void print() {
System.out.println( "Hello, World!" );
}
}
Within the main function, i re-instantiate the same class as i need to call a non-static method from within the static main method.
While this works, i am wondering is this a good way to do it? And how many instances of f are created.
How can i make sure f would be a singleton.
Thanks
About the first question: Only one instance of the class First is created.
About the second question:
The singleton pattern involves using a private constructor and a factory method. You cannot create a new instance of First without using the getInstance factory method, and all calls to getInstance will return the same instance.
class First {
private static First instance = null;
private First() {}
public static First getInstance() {
if (instance == null) {
instance = new First();
}
return instance;
}
}
class Second {
public static void main(String[] args) {
First f = First.getInstance(); //Always the same instance of First.
}
}
Related
I've been flustered over trying to figure out how to call a method from an instance of a class from a different class. For example:
public class Test1
{
public static void makeSomeInst()
{
Test1 inst = new Test1();
inst.fireTest();
}
public void fireTest()
{
System.out.println("fireTest");
}
public Test1()
{
}
}
no problem with understanding the above, but what If I want to do something to inst from a class called Test2, how would I do that? The below example doesn't work:
public class Test2
{
public static void main(String[] args)
{
Test1.makeSomeInst();
inst.fireTest();
}
}
And just to be extra clear, I get that I can call static references without instantiating, but I just want to know, in this specific case
What is the syntax to reference the test1 object called inst from the Test2 class?
what If I want to do something to inst from a class called Test2, how would I do that?
First of all you have to teach the Test2 class what Test1 is.
public class Test2
{
public doSomething()
{
inst.fireTest();
}
public Test2(Test1 inst)
{
this.inst = inst;
}
private Test1 inst;
}
Then teach the inst2 object what inst is.
public class Test1
{
public static void main(String[] args)
{
Test1 inst = new Test1();
Test2 inst2 = new Test2(inst); // <- new code
inst2.doSomething(); // <- new code
}
public void fireTest()
{
System.out.println("fireTest");
}
public Test1()
{
}
}
You only need one main to start the show. Flow of control can still pass through other objects. But at this point I wouldn't call these independent tests. I only used that name to match your code.
What you're looking at is something called reference passing. The fancy term for it is Pure Dependency Injection*. The basic pattern is to build an object graph in main. Once that's built call one method on one object to start the whole thing ticking.
In main you build every object that will live as long as your program does. What you wont find built here are objects that are born later, such as timestamps. A good rule of thumb is to build each of these long lived objects before doing any real work. Since they know about each other they can pass flow of control back and forth between them. There's a lot of power there and if not used well it can get confusing. Look into Architectural Patterns to help keep that simple.
The principle followed here is to separate use from construction. Following that allows you to easily change your mind about what talks to what in one place. It's nice when a design change doesn't force you to rewrite everything.
You have to save your instance somewhere.
If Test1 should be a singleton, you can do:
public class Test1
{
private static Test1 instance;
public static Test1 getInstance()
{
return instance == null ? instance = new Test1() : instance;
}
public static void main(String[] args)
{
Test1 inst = getInstance();
inst.fireTest();
}
public void fireTest()
{
System.out.println("fireTest");
}
}
and in Test2:
public class Test2
{
public static void main(String[] args)
{
Test1.getInstance().fireTest();
}
}
//Edit
As I just learned from #Thomas S. comment, singletons are not a good solution.
See #candied_orange's answer for a better implementation.
I took this example from a tutorial. Given below class was created to restrict multiple objects creation in same class.
package interview;
public class Test1 {
private static Test1 tstObj = null;
private Test1() {
}
public static Test1 createObject() {
if (tstObj == null) {
tstObj = new Test1();
}
return tstObj;
}
public void display() {
System.out.println("Singleton class Example");
}
}
But when I tried to create multiple objects from the same class in another class in same package I got succeeded.
package interview;
public class Test {
public static void main(String[] args) {
Test1 myobject = Test1.createObject();
myobject.display();
Test1 myobject1 = Test1.createObject();
myobject1.display();
Test1 myobject2 = Test1.createObject();
myobject2.display();
}
}
How come this happened or am I not understanding the consepnt of multiple object creation ???
Please help.
Your second and third calls to Test1#createObject() are not actually creating another instance of the singleton class, q.v. the code for the constructor:
public static Test1 createObject() {
// create a single instance the first time around
if (tstObj == null) {
tstObj = new Test1();
}
// otherwise return the instance which already exists
return tstObj;
}
Note carefully that the if statement only instantiates the singleton if the reference be null, which ideally should only happen the very first time your app calls createObject().
First of all, I am new in Java and I don't know yet a lot about it I just came up with this new idea.
Let's say I have a method methodCondition(String,String,String) where I want to be put in any class.
The scenario of code is below:
Where everything is started
public class MainClass{
public static void main(String... args)
{
//Whe everything started, call StartFunction from proccesshelper class to Start a Thread.
ProccessHelper phelper = new ProccessHelper();
phelper.StartFunction();
}
public void methodCondition(String data1, String data2, String data3){
//Do something about the data when this method is fire from Thread
}
}
A class where functions can call
public class ProccessHelper{
//Some function here
public void StartFunction(){
MyThread mythread = new MyThread();
Thread t = new Thread(mythread);
t.start();
}
//Some function here
}
A thread where methodCondition(String,String,String) is able to fire
public class MyThread implements Runnable {
volatile boolean StopThread = false;
public MyThread(){}
public void Stop(boolean stopThread){
this.StopThread = stopThread;
}
public void run(){
if(dontLoop){
while(true){
if(condition = true){
/*
* if the condition here is true then call "eventMethod" from any unkown class.
*/
methodCondition(String data1, String data2, String data3);
}
}
}
}
}
So my question is, it is possible that the MyThread can call methodCondition(String,String,String) in any class where it is register just like listening and waiting to be call?
Just like what I said, I don't know yet a lot in Java, I don't know what kind of function is this or if this is possible I just came up with this Idea.
So if anyone can tell,explain or give a link for any reference about what I am trying to achieve that will be very appreciated. I am also open for any clarification. Thank you!
If you want to call methodCondition from any class you must declare like static method. The statics methods can be called without instantiate the container class.
public static void methodCondition(String data1, String data2, String data3){
//Do something about the data when this method is fire from Thread
}
After declare like static you can call it directly:
MainClass.methodCondition(...);
All classes must be in the same package, or import MainClass where you want to use methodCondition.
If you don't know the class name, better put it in an interface and accept that interface as an input to your thread and call it from interface reference. This method could be inner to thread or can be a normal interface. Below is the example with inner interface.
Thread Code:
class MyThread implements Runnable {
interface interfaceName {
void methodName(String data1, String data2, String data3);
}
interfaceName interfaceReference = null;
// Other members declaration
private MyThread(interfaceName obj) {
interfaceReference = obj;
}
public static MyThread getInstance(interfaceName obj) {
if (obj == null) {
throw new NullPointerException();
}
return new MyThread(obj);
}
public void run() {
// Do your stuff
interfaceReference.methodName("", "", "");
// Do your stuff
}
}
Other Classes Example:
public class Temp implements MyThread.interfaceName {
public static void main(String[] args) {
Temp t = new Temp();
MyThread mt = MyThread.getInstance(t);
}
public void methodName(String data1, String data2, String data3) {
// Do your stuff
}
}
I am happy to found it and it is called Invoking Methods. And to be clear, what I really want is to find for specific name of method from unknown class and if it is exist then call it to fire specific task.
in Addition, the code I've done is below and it's work:
Class c=Class.forName("MainActivity");
Method m=c.getMethod("methodCondition", String.class, String.class, String.class); //The method has 3 String paramaters so I have to intialize it otherwise it will produce an error that the method was not found.
Object t = c.newInstance();
m.invoke(t,"Hello Word!", "this is", "to Invoke Method"); //Now invoke the method with the value or paramaters.
I am using this singleton class in Java and in one method, I need an object of a class which gets instantiated in Main. I am not knowing how to pass that object to this method because this code is written in the constructor of the singleton class as I need it to be executed as soon as the program starts.
Should I take out the code from the constructor and make it a standalone method which I call from Main (though I wouldn't prefer this) or is there another way?
Any ideas?
Code:
Main:
public static void main(String[] args) {
X x; // This is the object I need to pass to the singleton class
}
Singleton class:
public SomeSingletonClass {
private Queue<Y> someQueue; // Y is another class I have in my project
private SomeSingletonClass(){
someQueue.add(new Y(<some data>, <some data>, <here I need an object of X as the constructor needs it>);
}
}
I haven't added the entire code. Just a fragment where I am stuck.
You have two main options.
The first will produce howls of derision - and rightly so because it is a dark tunnel of hell.
public class X {
}
public class Y {
public Y(String s, X x) {
}
}
public class Main {
public static X x = new X();
}
public class SomeSingletonClass {
private Queue<Y> someQueue = new LinkedList<>();;
private SomeSingletonClass() {
someQueue.add(new Y("Hello", Main.x));
}
}
Here we make the X created by Main a public static so it is now, essentially, global state in parallel with your singleton.
Most readers will understand how nasty this is but it is the simplest solution and therefore often the one taken.
The second option is lazy construction.
public class BetterSingletonClass {
private BetterSingletonClass me = null;
private Queue<Y> someQueue = new LinkedList<>();
private BetterSingletonClass(X x) {
someQueue.add(new Y("Hello", x));
}
public BetterSingletonClass getInstance (X x) {
if ( me == null ) {
me = new BetterSingletonClass(x);
}
return me;
}
}
Note that I have made no effort to make this a real singleton, n'or is this thread-safe. You can search for thread safe singleton elsewhere for plenty of examples.
My Code:
(causes a Stack Overflow Error)
public class Overloads {
String uniqueID;
Overloads ov2=new Overloads();
public static void main(String[] args) {
System.out.println("IN MAIN");
}
public void setUniqueID(String theID) {
// II lots of validation code, and then:
uniqueID = theID;
System.out.println(uniqueID);
}
}
This Code Works Fine:
public class Overloads {
String uniqueID;
public static void main(String[] args) {
Overloads ov2=new Overloads();
System.out.println("IN MAIN");
}
public void setUniqueID(String theID) {
// II lots of validation code, and then:
uniqueID = theID;
System.out.println(uniqueID);
}
}
The presence of main method is not relevant here. The scope in which you have declared the variables, however, is very important.
Have you walked through what happens in the first version of the code?
Create new instance of Overloads
-> ov2 = Create new instance of Overloads
-> ov2 = Create new instance of Overloads
-> ov2 = Create new instance of Overloads
and so on. The variable ov2 is in scope of the class, thus 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.
The second version of the code only instantiates one instace of Overloads, in the scope of the main method. Thus creating one instance does not lead to the newly created instance creating new instance and so on..
You can do like this
public class Overloads {
String uniqueID;
static Overloads ov2 = new Overloads();
public static void main(String[] args) {
System.out.println("IN MAIN");
}
public void setUniqueID(String theID) {
// II lots of validation code, and then:
uniqueID = theID;
System.out.println(uniqueID);
}
}
this will create shared instance of Overloads, instantiation will be done only once, when class loaded