1

I am writing a simple Interface class as below. I need to make only one of its methods available to the user. The user using this class needs only the return value of this particular method (checkLink). Therefore I have declared this method alone as protected so it is visible only to the user calling the Iface class. Since the rest of the methods in the Class are to be used within the class they have been declared as private. I added Static keyword as these methods are sort of "stateless". I used static final keyword for the class variables as I wanted something like a C like #define.

Since I am C programmer I am still new to the Java world. Do take a look at the skeleton of my code and tell me if the declarations made are right in conveying the meaning.

package com.prog.Test;
import java.net.*;
import java.io.*;

public class Iface{   

    private static final int MSG_OK     =   0x01;
    private static final int MSG_NOK    =   0x00;   
    private static final int MSG_FAIL   =   0xFF;    

    private static byte[] getBytesFromUrl(URL link) throws IOException {
        ......                  
        return bytes;
    }               

    private static int[] msg_header(byte[] msg) throws Exception
    {
        int len = msg.length;
        System.out.println("len ="+len);
        int[] headerMsg =new int [3]; 
        headerMsg[0]= MSG_OK; 
            ......

        return headerMsg;
    }

    private static byte[] Tobyte(int[]src) {
            ....
    }

    protected static int checkLink (URL url ) throws IOException {

       byte[] rbuffer = null;
       byte[] hdr = null;
       int status = -1; 

        try{             
            rbuffer = getBytesFromUrl(url);
            ..
            ..
            hdr = Tobyte(msg_header(rbuffer));
            ...
            ...
            status = 0; 

        }catch (Exception e) {
            System.err.println("Exception:  " + e);
        }
        return status; 

  }
}

So when I use this Iface class in an Application, I call it this way:

public class Trial {  

    public static void main (String [] args ) throws IOException {

        URL url = new URL("http://localhost:8000/myfile");

        System.out.println("Calling Iface");

        int retval = Iface.checkLink(url);      

        System.out.println("retval ="+retval);
    }
}

I also tried this (after removing the static keyword in checkLink() method):

 public class Trial {  

        public static void main (String [] args ) throws IOException {

            URL url = new URL("http://localhost:8000/myfile");

            System.out.println("Calling Iface");

                Iface callInterface;

            int retval = callInterface.checkLink(url);      

            System.out.println("retval ="+retval);
        }
    }

Is there a difference?

user489152
  • 907
  • 1
  • 23
  • 42

5 Answers5

4

Calling static methods via an instance and via the class are functionally equivalent in Java. The following:

Iface.checkLink(<url>);

is functionally equivalent to

Iface foo = new Iface();  // or Iface foo;   but with the caveats below
foo.checkLink(<url>);

However, note that the latter is not recommended because it is confusing and unnecessary. It could be argued that it's only allowed because of a mistake by the Java language designers.

Caveat: In your example you're not initializing your Iface variable. You can still call static methods via this variable, however you would likely run into issues down the line if you were using it for anything but static methods (which you shouldn't be doing in the first place!).

In fact, you should probably go so far as to make this class uninstantiable since it appears to be a utility class with nothing but static methods.

Community
  • 1
  • 1
Daniel DiPaolo
  • 55,313
  • 14
  • 116
  • 115
  • I agree with "you shouldn't do this". I forgot to mention that in my answer. – Bart Vangeneugden Jul 20 '11 at 14:11
  • so the learning is that I should make my class itself non-instantiable. Or if I dont do that, atleast initialize it as above. But it is still advised to call static method via the class. – user489152 Jul 20 '11 at 14:31
  • @user489152 yes precisely, in the case of a class that is used specifically to house nothing but static methods, you should follow the steps in ["Java static class?"](http://stackoverflow.com/questions/1844355/java-static-class). And yes *definitely* only invoke static methods via the class. – Daniel DiPaolo Jul 20 '11 at 14:33
  • @Daniel DiPaolo: Of course if I have to remove that static keyword from checkLink method for the reasons mentioned by StriplingWarrior in his answer, then I will instantiate the class like your latter approach – user489152 Jul 20 '11 at 14:53
  • @user489152 yes, and you'll want to *not* make it uninstantiable as well, of course – Daniel DiPaolo Jul 20 '11 at 14:54
1

Yes, by doing this: Iface callInterface; you are creating an instance of the class Iface and therefore reserving some space in the memory. Howver, you're still executing a static method, so you can't use any of the instance methods/attributes.

So in terms of execution, there won't be any difference. In terms of memory/garbage collection, there will.

Bart Vangeneugden
  • 3,436
  • 4
  • 33
  • 52
  • That's not an instance of an object until you create and reference to an object... It's just a variable of that type. – Yochai Timmer Jul 20 '11 at 14:13
  • oh yes, you're right. He didn't call a constructor. Isn't this creating it in stack but not heap? – Bart Vangeneugden Jul 20 '11 at 14:19
  • 2
    Since the variable is never set to anything, the JIT will undoubtedly optimize this away. There will be no stack space reserved for the variable. – StriplingWarrior Jul 20 '11 at 14:22
  • @StriplingWarrior: So since I didn't call constructor for Iface, there will be no stack space for it? – user489152 Jul 20 '11 at 14:40
  • 1
    @user489152: Since you didn't *assign anything to the `callInterface` variable*, there will be no stack space allocated. Since you didn't call the constructor, there will be no heap space allocated. – StriplingWarrior Jul 20 '11 at 15:27
1

Sure there's a difference.

Static methods are not members of the object, they belong to the class.

So if checkLink() is static, then you should call it from the class itself: IFace.checkLink().

Calling it from a reference to an object will work, but logically it's not the right meaning. Because the method doesn't belong to the object, and won't work on the object's actual state.

Yochai Timmer
  • 48,127
  • 24
  • 147
  • 185
1

Technically, neither of the code examples you posted should work.

The protected keyword tells Java to only allow classes to access that variable if they extend the Iface class. You are not extending the class in your calling code, so neither approach to using the method should compile if the method is not public.

Be aware that making the method static means that callers will need to use the Iface class directly, making it impossible to use class inheritance. So if you will ever want to have another class that extends Iface and overrides the implementation of checkLinks, you'd want to make the method non-static.

If the method is non-static, you'd want to use it like this:

Iface callInterface = new Iface();
int retval = callInterface.checkLink(url);   

You may also want to do some research on the factory pattern and the dependency injection pattern, which give you more flexibility in determining which specific Iface implementation you want to use.

StriplingWarrior
  • 151,543
  • 27
  • 246
  • 315
  • :"Protected" means only subclasses and classes in the same package can access it. So when I use Iface class in an Application in the same package it should work right?'cos I just tested my code and it works.. – user489152 Jul 20 '11 at 14:56
  • 1
    @user49152: That's true. I had assumed that the calling code was in a different package. The `protected` keyword is best to use when you're expecting someone to extend your class. Otherwise, if you don't specify any access keywords, the default access level will allow other classes in the same package to access the method, while preventing subclasses of it in other packages from using it. See http://download.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html – StriplingWarrior Jul 20 '11 at 15:32
0

I guess that your question would be mor accurate like "What does static mean?".

For me simply "static" means, that those variables are there only once per class, all others are in every object coming from that class.

Xote
  • 21
  • 2