Can someone help me to understand why java is trying to make an instance of a before b. And also, why it is looping between line 2 and line 3?
public class Winterfell {
private Winterfell a= new Winterfell();
public Winterfell() throws Exception {
throw new Exception("Fire and Ice");
}
public static void main(String[] args) {
try {
Winterfell b = new Winterfell();
System.out.println("Surprise!");
} catch (Exception ex) {
System.out.println("I told you so");
}
}
}
This will cause a StackOverflowError.
By having a field referencing a new object of the same class or by making a new object of the same class in the constructor you have an infinite number of calls to create a new Winterfell object.
That is why it is looping.
To fix this you likely want to remove private Winterfell a= new Winterfell(); so that a single Winterfell object is created.
private Winterfell a= new Winterfell();
Is invoked prior to invoking the constructor of Winterfell because it's a data member. Check out the Oracle documentation for object construction for more info.
Related
I am solving the below interview question. It's throwing a NullPointerException, but I do not understand how the value of c is null. I already initialized it in the go() method.
package swain.javainterviewhub.blogspot.in;
class Chicks{
synchronized void yack(long id){
for(int x=1;x<3;x++){
System.out.println(id+" ");
Thread.yield();
}
}
}
public class JavaInterviewHub implements Runnable {
Chicks c;
public static void main(String[] args) {
new JavaInterviewHub().go();
}
void go(){
c=new Chicks();
new Thread(new JavaInterviewHub()).start();
new Thread(new JavaInterviewHub()).start();
}
#Override
public void run() {
c.yack(Thread.currentThread().getId());
}
}
Console:
Exception in thread "Thread-0" Exception in thread "Thread-1" java.lang.NullPointerException
at swain.javainterviewhub.blogspot.in.JavaInterviewHub.run(JavaInterviewHub.java:28)
at java.lang.Thread.run(Unknown Source)
java.lang.NullPointerException
at swain.javainterviewhub.blogspot.in.JavaInterviewHub.run(JavaInterviewHub.java:28)
at java.lang.Thread.run(Unknown Source)
Since Chicks.yack() is synchronized, you probably meant for both threads to use the same instance of Chicks, which means you probably meant for both threads to use the same instance of JavaInterviewHub, in which case you probably meant to start both threads with the instance that was created in main().
If that's all true, then you need to use this when creating the threads:
void go(){
c=new Chicks();
new Thread(this).start();
new Thread(this).start();
}
As for the question of when to create an instance of Chicks, and therefore assign a value to c, you have 3 choices:
Leave the code as-is. A bit obscure, but valid.
Do it in a constructor.
Do it when declaring c. Easiest.
Option 2: Constructor
private JavaInterviewHub() {
this.c = new Chicks();
}
Option 3: Declaration
private final Chicks c = new Chicks();
When you create a thread like this:
new Thread(new JavaInterviewHub()).start();
A new instance of JavaInterviewHub is created. In this instance c is not set anywhere, so when the run method is executed, a NullPointerException is thrown.
One way to solve the issue is to initialize c in JavaInterviewHub's constructor. Another would be to initialize c where it's declared. See the acepted answer for more information.
I have the code:
public class RssReader {
private File dataFile = new File("data.dat");
private FileInputStream dataStream = new FileInputStream("data.dat");
boolean fileExists;
public static void main(String[] args) {
}
}
My question is, can I put FileInputStream or any code that requires Try/catch as a global function?
Yes you can. you can declare that main method throws an Exception of any kind, i.e.
public static void main(String[] args) throws IOException {
}
And you can omit the try-catch block in the code.
I would highly suggest NOT doing that, though. First of all, try-catch blocks exist for a reason. They are here to catch exceptions that you might foresee but have no control of (i.e. bad file format). Second of all, they will let you close the streams in finally blocks even if the exception happens.
Yes you can if you let your constructor throws the exception :
class RssReader {
private File dataFile = new File("data.dat");
private FileInputStream dataStream = new FileInputStream("data.dat");
boolean fileExists;
RssReader()throws IOException{}
}
Then each time you will construct a new RssReader object, the method that handle this construction should throws it too (like darijan said), or you can create a try-catch block in this method :
public void someMethod() throws IOException {
RssReader r = new RssReader();
}
or :
public void someMethod() {
RssReader r;
try {
r = new RssReader();
} catch (IOException e) {
e.printStackTrace();
}
}
You may add that code by signing the method with throws Exception. But it is not recommended when you have an stream reader or something like that because often you gotta close the stream or flush the writers.
I think you should think about it when you need to open or close a stream object.
There are several things you can do and several you can't:
You can't initialize a variable with code that can throw a checked exception. The compiler will complain. So your line beginning private FileInputStream ... is illegal.
You can't use the instance variables inside the static main() method. The compiler will again complain once you put ... dataStream ... inside main().
You can put a throws IOException on the main method.
One way to deal with these things is to do this:
public class RssReader {
public static void main(String[] args) throws IOException {
File dataFile = new File("data.dat");
FileInputStream dataStream = new FileInputStream("data.dat");
boolean fileExists;
... use the variables here ...
}
}
which will toss you out to the command line if you run the program and, for example, the file doesn't exist. An error message and stack trace will be printed if that happens.
What I did up there is move all the variables into the scope of the main() method. Then I added the throws on the method so it will let whatever basic part of Java calls main() handle the exception.
Or you could do something another way like this:
public class RssReader {
private static File dataFile = new File("data.dat");
private static FileInputStream dataStream;
static {
try {
dataStream = new FileInputStream("data.dat");
} catch (IOException e) {
throw new RuntimeException(e); // this isn't a best practice
}
}
static boolean fileExists;
public static void main(String[] args) {
... use the variables here ...
}
}
which will do the same thing if there is a problem with finding the file. Out to the command line and print messages.
This hides the possible checked exception inside a static initializer block with a try-catch around it. The checked exception is turned into an unchecked exception. It also makes all the variable static so they can be used in the static method main()
One more possible solution that's an even better way:
public class RssReader {
private File dataFile = new File("data.dat");
private FileInputStream dataStream;
boolean fileExists;
public RssReader() throws IOException {
dataStream = new FileInputStream("data.dat");
}
public void doTheWork() {
... use all the variables here ...
}
public static void main(String[] args) {
try {
reader = new RssReader();
reader.doTheWork();
} catch (IOException e) {
System.out.printf("File 'data.dat' not found. Exiting ...");
}
}
}
which is the one I like best. It gives you control over what happens if an exception happens so we print an informative message and tell them the program is finished. All the variables are instance variables inside the object instance created in the main() method. Main does almost nothing but create the instance and tell it to get to work. Main also decides what to do if it fails.
The changes are to move everything to instance scope and out of static scope, except catching the fatal exception. You can leave your variables at the top where they are easy to read. The method that does the work is given a name to describe what it does.
I'm trying to have the file "TutorialMap" used as the map in this TutorialMission. I keep getting told that the MapReader "reader" needs to be static, but when it's static, I get told "Unhandled exception type FileNotFoundException" with the error on the constructor of reader.
static MapReader reader = new MapReader("TutorialMap");
static Territory[][] missionMap = reader.getMap();
public TutorialMission() throws FileNotFoundException {
super(missionMap, Size, AircraftCarrierID, AircraftCarrierID);
}
The Super class' constructor:
public class MissionIF extends Map {
public MissionIF(Territory[][] load, String size, int StartingMoney, int powerLevel)
{
// Set money per mission.
super();
Thanks for your time.
I don't know why it must be static, but since the constructor throws the checked exception, it has to be handled at the place of calling. Therefore do something like this:
static MapReader reader = null;
static Territory[][] missionMap = null;
static {
try {
reader = new MapReader("TutorialMap");
} catch(FileNotFoundException e) {
e.printStackTrace();
}
missionMap = reader.getMap();
}
Compiler requires your reader to be static because you invoke it when initializing other static variable missionMap.
When you mark it as static compiler is going forward and sees that you do not catch exception thrown from your constructor TutorialMission.
Since I do not understand what do you really want to do I can just suggest you:
If you want all this stuff to be static initialize reader into static initializer and catch exception:
static MapReader reader;
static {
try {
reader = new MapReader("TutorialMap");
} catch(FileNotFoundException e) {
throw new IllegalArgumentException(e);
}
}
Your checked exception is now wrapped by unchecked one.
Alternatively (if you do not really want to hold this data in static variables just remove static modifier and perform initalization in constructor:
public TutorialMission(MapReader reader, Territory[][] missionMap) throws FileNotFoundException {
super(missionMap, Size, AircraftCarrierID, AircraftCarrierID);
missionMap = reader.getMap();
}
Now caller is responsible on creating and passing here the reader.
surrounds the code throwing "Unhandled exception type FileNotFoundException" with try catch block. Your are getting this exception because its a checked exception and you are forced to handle this. i would suggest using IDE like eclipse(if you are not using this already) which is really helpful for development.
try {
reader = new MapReader("TutorialMap");
} catch(FileNotFoundException e) {
throw new RunTimeException(e);
}
Constructor and method not working as expected in Java program
I have the following code:
package principal;
public class Principal {
public static void main(String[] args) {
Thread filosofos[]=new Thread[5];
for (int i=0;i<5;i++) {
System.out.println("loop");
filosofos[i]=new Thread();
filosofos[i].start();
}
// TODO Auto-generated method stub
}
}
package principal;
public class Filosofo implements Runnable{
static final int tamanho=5;
static int talheres[]=new int[tamanho];
static Semaforo semaforo= new Semaforo(1);
static int quantidade=0;
int id;
public Filosofo(){
System.out.println("Construtor iniciado.");
for (int i=0;i<tamanho;i++) {
talheres[i]=0;
}
quantidade++;
id=quantidade;
}
public void run () {
System.out.println("Filosofo "+id+" iniciado");
try {
// Filosofo pensando
Thread.sleep(1000);
} catch (Exception e) {
}
semaforo.down();
System.out.println("Filosofo "+id+" comendo");
semaforo.up();
}
}
The program should exhibit the string "Construtor iniciado." and the other 2 strings of method run. However when I run the code nothing happens only output that I receive is
loop
loop
loop
loop
loop
why the string of the constructor is not showing up? Why the method run is not running as expected? It looks like the constructor and the method run are not running at all, and I don't know what is going wrong.
You have declared class Filosofo but you never create a single instance of it.
Perhaps you want to pass a new instance of Filosofo as thread constructor parameter for each thread?
package principal;
public class Principal
{
public static void main(String[] args)
{
Thread filosofos[]=new Thread[5];
for (int i=0;i<5;i++) {
filosofos[i]=new Thread(new Filosofo());
filosofos[i].start();
}
}
}
Except this, instead of using a static field for counting Filosofo instances and assign them an id, why you don't just pass the id in the constructor?
Also the other fields, don't need to be static, pass the shared fields, like semaforo, in the constructor and copy them in a class field.
I don't know the meaning of talheres field and I don't understand why you reinitialize a static field in each instance constructor, maybe you can just initialize once in main and pass that field in the constructor of each Filosofo, as you know, arrays are not copied, only a reference to them is copied.
Also instead of catch (Exception e) you should use catch (InterruptedException e).
You should do something useful with the exception, like printing it.
If you intend to ignore an exception at least you should add a very detailed comment on why you are doing that.
You never instantiate any Filosofo, just Threads.
Could you tell me can be some case when exception is throwing in constructor and object is not null. I mean some part of object is created and another is not.Like this
public Test(){
name = "John";
// exception
// init some other data.
}
I understand in this sitiation object Test will be null, but Can be situation that object test cannot be null (delete block of exception not answer :) ) ?
A class instance creation expression always creates a new object if the evaluation of its qualifier and arguments complete normally, and if there is space enough to create the object. It doesn't matter if the constructor throws an exception; an object is still created. The class instance creation expression does not complete normally in this case, though, as it propagates the exception.
However, you can still obtain a reference to the new object. Consider the following:
public class C {
static C obj; // stores a "partially constructed" object
C() {
C.obj = this;
throw new RuntimeException();
}
public static void main(String[] args) {
C obj;
try {
obj = new C();
} catch (RuntimeException e) {
/* ignore */
}
System.out.println(C.obj);
}
}
Here, a reference to the new object is stored elsewhere before the exception is thrown. If you run this program, you will see that the object is indeed not null, though its constructor did not complete normally.
No. Look at the client code:
Test myObj = null;
try {
myObj = new Test();
} catch(MyException e) {
System.out.println("" + myObj);
}
Here, when exception occurs, the '=' operation is not executed. Your code goes straight to the catch block and myObj stays null.
No. If exception occurs during the instantiation of the object, it will not be created.
Anyway, you would you write it?
MyObject obj = new MyObject();
// This code will not be reachable in case of an Exception
or:
MyObject obj = null;
try {
obj = new MyObject();
} catch (AnyException e) {
}
// Here, either obj is created correctly, or is null as an Exception occurred.
public Test() {
name = "John";
try {
// exception
// init some other data.
} catch(AnyException e) {
// catch
}
}
The above code makes sense as per your expectation.