in Java - WTF does "static" do?

notfred

Lifer
Feb 12, 2001
38,241
4
0
Most of this is familiar from C (why they had to change the name to "boolean" I don't know), but I'm not getting static. What's the purpose of it? my compiler keeps bitching at me about "Non-static method checkSignatute(java.io.FileInputStream) cannot be referenced from a static context"

<-- confused.
 

Noriaki

Lifer
Jun 3, 2000
13,640
1
71
static is a Class member, that does not need to be instantiated to be used.
non-static is an Object member, and you need to instantiate the class to use it.

for example, say we have two methods:

class myClass {
static static_method() { ... }
non_static_method() { ... }
}

to call the static one you go:

myClass.static_method();

if you want to use the non-static you have to say:

myClass myObj = new myClass();
myObj.non_static_method();



Here's a concrete example:
Stuff like java.lang.Math uses a lot of static methods, so you use Math.abs(x); for example.
If abs were not static, you'd have to say:

Math M = new Math();
M.abs(x);

And that would just be weird.

But other things, like OuputStreams...have non-static methods.

You say:
OutputStream o1 = new OutputStream();
OutputStream o2 = new OutputStream();

then:
o1.write();
o2.write();

and those have different results obviously.
you couldn't just have one static write() method or else you'd have to say:
OutputStream.write();

And how would it know which one you wanted to write to?
 

trasko

Member
Sep 13, 2002
35
0
0
Its been too long since I did Java or any real OO stuff, but...

When you're dealing with objects, you can have the overall "class" which is a sort of blueprint for the object and you can also have "instances" of an object. There is only one "class" but there can many instances of a class.

So a static method or a static variable is one that acts in the context of the overall class and not per instance.

The example always give is this:

when you create a new Widget, in the constructor you can increment the STATIC variable iNumWidgets and that will keep count of how many INSTANCES of the class Widget have been made. If, on the other hand you mistakingly made the counter variable a non-static variable, when you create a new Widget that variable will be 1 (...) -- and this variable will be 1 for each instance you create.

Anywho, I suck at explanations and its been too long since I messed with java. the smart people of AT will come to your rescue no doubt. if not, RTFM :)
 

Ameesh

Lifer
Apr 3, 2001
23,686
1
0
static in the context of a function means that you dont create an instance of the class to call the function:

i.e.


if i have

public class foo
{
public:
static boolean AreStaticFunctionsCool;
}


you would call the function by sayin foo.AreStaticFunctionsCool()
 

notfred

Lifer
Feb 12, 2001
38,241
4
0
Originally posted by: Ameesh
are you trying to use FileInputStream without creating an instance of the class?

No, this worked fine when I had the FileInputStream inside the main method.

I moved a bunch of code to a new method, and I got that error when I tried to call the methos (Which takes a FileInputstream as a parameter)
 

notfred

Lifer
Feb 12, 2001
38,241
4
0
I've got two files now. I get the same error every time I try to call one of my other methods from inside Ping.main it'll just substitute the name of whatever method I call into the middle of the error mesage


file #1:

import java.io.*;

public class Ping {
public static void main(String[] args){
System.out.println("About to read \"/Users/tyler/test.png\"\n");
File testPNG = new File("/Users/tyler/test.png");
if(testPNG.exists()){
System.out.println("test.png exists\n");
}
else {
System.out.println(testPNG);
System.exit(0);
}
ReadPng.startRead("/Users/tyler/test.png");
}
}

file #2:

import java.io.*;

public class ReadPng{
public void startRead(String filename){
try {
FileInputStream test = new FileInputStream(filename);
if(checkSignature(test)){
System.out.println("Looks like a valid PNG file");
}
}
catch(FileNotFoundException e){
System.out.println("File does not exist\n");
}
catch(IOException e){
System.out.println("Some IO Exception occured\n");
}
}

public boolean checkSignature(FileInputStream image){
int signature[] = {137,80,78,71,13,10,26,10};
int valid = 0;
for (byte $i=0;$i<8;$i++){
int current = image.read();
if(current == signature[$i]){
valid++;
}
}
if(valid == 8){
return true;
}
else {
return false;
}
}
}
 

FeathersMcGraw

Diamond Member
Oct 17, 2001
4,041
1
0
"static" refers to variables and methods that are referenced from class, not instance, context.

Static variables are shared between all members of a class. Say you have two objects a and b of the following class Foo:

public class Foo
{
public static int bar;
public int baz;

static public void doFoo()
{
}

public String toString()
{
System.out.print(bar);
System.out.print(" ");
System.out.println(baz);
}
}

a.bar = 1;
b.bar = 2;
a.baz = 1;
b.baz = 2;

System.out.println(a);
System.out.println(b);

will print the following:

2 1
2 2

Since all instances of the class share the same static variables, the value assigned to b.bar overwrites the value of a.bar.

Static methods can be called without a class instance by using the class name. Thus, you can call doFoo by using Foo.doFoo(), a.doFoo(), or b.doFoo(). Static methods can only reference static variables, so doFoo can use bar, but not baz.
 

Ameesh

Lifer
Apr 3, 2001
23,686
1
0
if you dont understand why pm and we can chat, im goin home now. ill be back in a bit.
 

FeathersMcGraw

Diamond Member
Oct 17, 2001
4,041
1
0
Originally posted by: notfred
ReadPng.startRead("/Users/tyler/test.png");

This is probably what the compiler is complaining about, since you're treating method startRead as a static method.

You should declare startRead as a static method so that it can be invoked without needing an instance.

You could also declare a variable of type ReadPng and then invoke startRead from it:

ReadPng testReadPng = new ReadPng();
testReadPng.startRead("/Users/tyler/test.png");

 

notfred

Lifer
Feb 12, 2001
38,241
4
0
Originally posted by: Ameesh
make checkSignature() a static function

and you should be fine.


If I do that it just complains about the FileInputStream. Basically, it complains as soon as I try and access anything that's not static. And main is required to be static. So, how do I do this without making everything in the whole program static? there's got to be some way to break out of this chain of static statements.
 

Ameesh

Lifer
Apr 3, 2001
23,686
1
0
oh you might want to change


if(checkSignature(test)){ ----> if(this.checkSignature(test)){

its clearer what you are trying to do.

 

Descartes

Lifer
Oct 10, 1999
13,968
2
0
Most of this is familiar from C (why they had to change the name to "boolean" I don't know)

There's no bool in anything pre-ANSI C99.

So, how do I do this without making everything in the whole program static? there's got to be some way to break out of this chain of static statements.

Create an instance of the class that contains your static method. This is way the OO works; you can't "break out" of it. Static methods are stored once in memory, regardless of how many instances may exist on the heap. Instance methods (anything not static) are stored for every instance on the heap. e.g.

class Test
{
public static void main(String[] args)
{
System.out.println("Test");
Test t = new Test();
t.Foo();
}

public void Foo()
{
System.out.println("Foo");
}
}

If it's an instance method, just create an instance of it. main is static because you only have one entry point to your application.
 

FeathersMcGraw

Diamond Member
Oct 17, 2001
4,041
1
0
Originally posted by: notfred
If I do that it just complains about the FileInputStream. Basically, it complains as soon as I try and access anything that's not static. And main is required to be static. So, how do I do this without making everything in the whole program static? there's got to be some way to break out of this chain of static statements.

You're not instantiating any objects. If you don't create any object instances, you're forced to refer to all your methods (and your methods can only reference member variables) from a static context.
 

notfred

Lifer
Feb 12, 2001
38,241
4
0
Originally posted by: FeathersMcGraw
Originally posted by: notfred
ReadPng.startRead("/Users/tyler/test.png");

This is probably what the compiler is complaining about, since you're treating method startRead as a static method.

You should declare startRead as a static method so that it can be invoked without needing an instance.

You could also declare a variable of type ReadPng and then invoke startRead from it:

ReadPng testReadPng = new ReadPng();
testReadPng.startRead("/Users/tyler/test.png");

Thanks ;)

that was enough information for me to get it working!

I'm 10 minutes late to a class (not a java class... it's bio...) now, so I have to go :)

 

Noriaki

Lifer
Jun 3, 2000
13,640
1
71
Originally posted by: notfred
Originally posted by: Ameesh
make checkSignature() a static function

and you should be fine.


If I do that it just complains about the FileInputStream. Basically, it complains as soon as I try and access anything that's not static. And main is required to be static. So, how do I do this without making everything in the whole program static? there's got to be some way to break out of this chain of static statements.

Why do you want to "get out of this chain of static statements?"

You can very easily, like this:

ReadPng myReadPng = new ReadPng();
myReadPng.startRead(...);

but why do you want to?

just make startRead and checkSignature static then you can call ReadPng.startRead() the way you are now.

You don't have any real need to have more than one copy of the checkSignature and startRead methods do you?

You only need one copy, they are what I would call "Utility" methods.
Static is exactly what you want a utility to read.

If you wanted to create a new copy of startRead and checkSignature to go with every PNG file you have, then you leave the methods non-static, but you have to instantiate ReadPng.

The way you have your code structured right now there is no good reason to do that.

I don't see why you want to not use static methods. But it's easy to do if you really want to, just with a new. Without an instantiation (call to new) you can never move from static to non-static.