Help with java socket.

F

Franklin Lee

I get one program as below:
*************************************************************
import java.net.*;
import java.io.*;

public class SimpleServer {
public static void main(String args[]) {
ServerSocket s;

// Register your service on port 5432
try {
s = new ServerSocket(5432);
} catch (IOException e) {
// ignore
}

// Run the listen/accept loop forever
while (true) {
try {
// Wait here and listen for a connection
Socket s1 = s.accept();

// Get output stream associated with the socket
OutputStream s1out = s1.getOutputStream();
DataOutputStream dos = new DataOutputStream(s1out);

// Send your string!
dos.writeUTF("Hello Net World!");

// Close the connection, but not the server socket
dos.close();
s1.close();
} catch (IOException e) {
// ignore
}
}
}
}
****************************************************************************
***
I use javac to compile it.
And it always report below error:
SimpleServer.java:19: variable s might not have been initialized
Socket s1 = s.accept();
^
1 error

But I think I have initialize it as :s = new ServerSocket(5432);

So could you tell me the reason and how to fix it.

Thank you!

Franklin
 
R

Roedy Green

ServerSocket s;

// Register your service on port 5432
try {
s = new ServerSocket(5432);
} catch (IOException e) {
// ignore
}
If you had an exception the code would jump out the try block without
ever setting s. you can fix this most simply by typing

ServerSocket s = null;

This not a very nice value, but at least it is a value.
 
T

Tony Morris

If an exception is thrown, it will not have been initialised.

You have to learn a few things:
a) what the definition of "scope" is, in terms on local variables
b) appropriate exception handling (ignoring checked exceptions is A Bad
Thing which, in a perfect world, would result in some physical torture on
those who do it)
c) when you think your compiler is wrong, say to yourself 3 times "I'm
wrong, the compiler is right" (at least, until you gain enough experience to
make better informed judgements).

--
Tony Morris
(BInfTech, Cert 3 I.T.)
Software Engineer
(2003 VTR1000F)
Sun Certified Programmer for the Java 2 Platform (1.4)
Sun Certified Developer for the Java 2 Platform
 
F

Franklin Lee

It works.

Thank you!

But I'm not clear why this happen.
why I need : ServerSocket s = null;

So could you explain more detail.

Franklin
 
F

Franklin Lee

HiTony,

a) I have defined s before try block, so it's not one scope problem.
I just want to know that why I use: ServerSocket s = null; It works.
But ServerSocket s ; It doesn't work.

b) This is one simple example, I didn't add catch block.

c) I think I'm wrong, not compiler. But I don't know the reason.

Thank you!

Franklin
 
A

Adam

Franklin Lee said:
It works.

Thank you!

But I'm not clear why this happen.
why I need : ServerSocket s = null;

So could you explain more detail.

In Java local variables are not initialised
with zeros, false's or nulls (like instance variables).
So before first use of a local variable
you have to initialise it, and that's
what compiler tells you to do:
'variable s might not have been initialised.
Declaring a variable does not mean initialising it.

This:
void someMethod(boolean someCondition)
{
String s;
if(someCondition) s = "Hello";

System.out.println(s);
}

would not compile either.
What should be printed if someCondition were false?
As 's' is local, so is not initialised,
the construct is inconsistent.

Adam
 
F

Franklin Lee

Thank you, Adam!

I understand.

But I still have question: in fact I use try block to initialize it later.
And I think try block will always run. So it means that it will always
initialized. But why it doesn't work.
Anothe one: I tried to use : ServerSocket s = new ServerSocket(5432); to do
initialize. but it still failed and report that need exception.
So I can only use ServerSocket s = null ; to do it.

Franklin
 
G

Gordon Beaton

But I still have question: in fact I use try block to initialize it
later. And I think try block will always run. So it means that it
will always initialized. But why it doesn't work.

Anothe one: I tried to use : ServerSocket s = new
ServerSocket(5432); to do initialize. but it still failed and report
that need exception.

Neither you nor the compiler can know that the code will always
succeed. The ServerSocket constructor *will* fail if you try to run
your application a second time while the first instance is still
running.

Whenever a constructor or method declares that it can throw an
exception (as the ServerSocket constructor does), the caller must
either catch it, or itself declare that it can throw the exception
(propagating it upwards).

/gordon
 
J

Johan Poppe

Franklin Lee skrev:
Thank you, Adam!

I understand.

But I still have question: in fact I use try block to initialize it later.
And I think try block will always run. So it means that it will always
initialized. But why it doesn't work.

No, if there is an exception somewhere in the try block, all of the
try block will not run. In your case, if there was an exception in the
ServerSocket constructor, you never get a ServerSocket back and you
don't have anything to initialize 's' with.

One point is that the compiler is somewhat dumb when it comes to
analyzing which code always execute and which code only execute in
some circumstances. For example, in both of these examples there are
no actual chance that the s variable will not have not been
initialised in the last line, but IIRC all compilers will complain
anyway:
1)
String s;
int x = 5; //or int x = someMethodThatGivesAnInt();
if (x == 5) {
s = "x is 5 ";
} else if (x > 5) {
s = "x is larger than 5";
} else if (x < 5) {
s = "x is smaller than 5";
}
System.out.println(s.length());

2)
String s;
try {
s = "a string";
someMethodThatCanCauseIOException();
} catch (IOException ioe) {
something();
}
System.out.println(s.length());

This can be a bit annoying, but you just have to accept it as a fact
of life and do a default initialization before any conditional blocks.

Anothe one: I tried to use : ServerSocket s = new ServerSocket(5432); to do
initialize. but it still failed and report that need exception.

Yes, the constructor can cause an exception, and you have to either
catch it or specify that it should be thrown higher up.
So I can only use ServerSocket s = null ; to do it.

Yes. Note that this means that if the ServerSocket constructor causes
an exception, you'll then get a NullPointerException at the line the
compiler now complains about.

Another option is to put _all_ code using the variable in question
inside the try block:

try {
ServerSocket s = new ServerSocket(5432);
s.accept();
someMore();
} catch (IOException ioe) {
something();
}

I'm not sure how that will work out for you in practice, though.
 
R

Roedy Green

a) I have defined s before try block, so it's not one scope problem.
I just want to know that why I use: ServerSocket s = null; It works.
But ServerSocket s ; It doesn't work.

Let's say you tried to be clever like this:

ServerSocket s = new ServeSocket(8080);
// Register your service on port 5432
try {
s = new ServerSocket(5432);
} catch (IOException e) {
// ignore
}

Now what happens if socket 8080 fails? you have no try catch to deal
with it.

If you try this


// Register your service on port 5432
try {
ServerSocket s = new ServeSocket(8080);
s = new ServerSocket(5432);
} catch (IOException e) {
// ignore
}

Then s will be out of scope.

If you try this:

// Register your service on port 5432
ServerSocket s;
try {
s = new ServeSocket(8080);
s = new ServerSocket(5432);
} catch (IOException e) {
// ignore
}

it is possible that both either of 8080 or 5432 could fail. and s
would have NO value not even null when it falls out the bottom.

Hence you must put something in to start that won't raise an
exception. e.g. null.

// Register your service on port 5432
ServerSocket s= null;
try {
s = new ServerSocket(5432);
} catch (IOException e) {
// ignore
}
 
J

Johan Poppe

Roedy Green skrev:
If you try this:

// Register your service on port 5432
ServerSocket s;
try {
s = new ServeSocket(8080);
s = new ServerSocket(5432);
} catch (IOException e) {
// ignore
}

it is possible that both either of 8080 or 5432 could fail. and s
would have NO value not even null when it falls out the bottom.

Huh? That's the first time I've heard of a "NO value not even null".
Hence you must put something in to start that won't raise an
exception. e.g. null.

A(n explicit) null value will also cause an exception.

However, requiring _some_ kind of initialisation, possibly null,
forces the programmer to be aware of the possible problem.
 
C

Christophe Vanfleteren

Johan said:
Roedy Green skrev:


Huh? That's the first time I've heard of a "NO value not even null".

Maybe Roedy should have said "no specific value". As s wouldn't be properly
initialised, it could point to anything, and you can't be sure to what.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,189
Members
46,735
Latest member
HikmatRamazanov

Latest Threads

Top