I am coming from a C++ background, so I am used to the main function not being able to access private data members of an instance.
However, the case with Java is different as main is a part of the public class, and can thus access the private data.
Why is it that a static method is given access to private data even though it does not belong to the calling instance? Is there any way I can avoid this from happening?
Here's a little snippet to explain what I mean:
public class Main
{
private int x = 5;
public static void main(String[] args) {
Main ob = new Main();
System.out.println(ob.x);
}
}
I want x to be inaccessible from main and that I have to use an accessor method for the same.
There is no way to protect "a class from itself". Private means that the current class (and only the current class) can access the field.
If you had a private field that no method could access, you could never read or update its value and thus render it unneccessary. By declaring a field private, you prohibit anybody outside your current class to access the field.
Read about visibility here: https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html
Related
This question already has answers here:
What does the 'static' keyword do in a class?
(22 answers)
Cannot make a static reference to the non-static method
(8 answers)
Closed 5 years ago.
For some reason when I'm trying to call methods using a main method or try changing variables declared outside the main method I get forced into having to change everything to static. This is fine in places but when it comes to needing to change values later in the code for example using a Scanner for input the main method just takes it to a whole new level trying to make me change the Scanner library etc.
This example shows what happens if I try calling a method.
This example shows what happens when I try alter the value of a variable declared outside my main method.
I have never faced an issue like this before when writing java code I've tried recreating the classes/ project files etc but nothing works. I've tried looking everywhere for a solution but I can't seem to find one probably due to the fact that I don't know what to search for. I've probably made myself look like a right idiot with my title haha! Any suggestions people?? Thanks in advance!
Maisy
It can be a bit confusing to get out of "static land" once you are in your main() method. One easy way is to have another object contain your "real" (non-static) top level code and then your main method creates that object and starts it off.
public static void main() {
MyEngine engine = new MyEngine();
// core logic inside of start()
engine.start();
}
I hope that this was clear enough for you. Good luck Maisy!
When calling methods form a main you have to instantiate the class they are in, unless it's a static function
this is because that a class is a sort of template and there is nothing saved about it before it get instantiated
public class TestClass{
public static void main(String[] args){
TestClass testClass = new TestClass();
testClass.method();
}
public method method(){}
}
in the example above i instantiated a TestClass and then called on the testClass instance
there is some functions and variables on classes you might want static, because a static on a class is shared between ALL instances, and can be called on the class, say you want to know how many instances were created then something like this can be done.
public class TestClass{
public static void main(String[] args){
TestClass testClass = new TestClass();
testClass.method();
System.out.print(TestClass.instances +""); // note that i call on
//the class and not on an instance for this static variable, and that the + ""
//is to cast the int to a string
}
public static int instances = 0; // static shared variable
public TestClass(){instances++;} // constructor
public method method(){}
}
You need to do some Object Oriented Programming tutorial and to learn some basic.
As answer for your problem to call without using static you have to create an instance of the main Class
let suppose the following class Foo
public class Foo{
private int myVarInteger;
public int getMyVarInteger(){ return this.myVarInteger;}
public void setMyVarInteger(int value){this.myVarInteger = value;}
public static void main(String[] args){
Foo myClassInstanceObject = new Foo();
// now we can access the methods
myClassInstanceObject.setMyVarInteger(5);
System.out.println("value ="+myClassInstance.getMyVarInteger());
}
}
If I am not wrong, how many ever same Strings are created, only in only place it is stored by using String interning. If so, what is the use of making a Sting static if it is already being stored in only one place in memory which is nothing but acting as if it was a static variable. Thanks.
Static Strings can be accessed outside the class without creating the class's variable. Example of this is:
public class Stuff {
public static final String foo = "foo";
}
Here is an example of calling the variable foo (while still retaining it's contents of foo):
public class Application {
public static void main(String[] args) {
System.out.println(Stuff.foo);
}
}
As mentioned, I did not have to initialize Stuff in Application.
If you want to access it staticly outside of a class without initializing the class, then you make it static
You may want a class to access that String value but you do not want to initialize the class which holds the String. This is useful if one class is using the String but not using the rest of the class that holds the String.
I have main class with a private static method. I want to access this method from another java class. I tried some ways,however they didnt work. How can I access the method?
below main class like this;
public class RandomGenerate {
public static void main(String[] args) throws Exception {
System.out.print.ln("main method");
}
private static synchronized void createRandom(PersonObj person, int number, List s) {
System.out.println("deneme");
}
}
And I want to call createRandom from another java class like this;
public class Deneme {
RandomGenerate rg = new RandomGenerate();
RandomGenerate.createRandom(person, number, sList);
}
Then, netbeans shows method has private access.
You shouldn't access a private function/variable from outside of that class. If you need to access a private variable of a class, you can create an accompanying getter for that variable, and call the getter function on the class.
For functions, if the class you are trying to access the function from is in the same package, or is a subclass as the class with the function, change private to protected. protected allows members in the same package, or subclasses, to access the item, but nothing outside of the package.
A good read on visibility in Java is: http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html
That shows a table:
Access Levels
Modifier Class Package Subclass World
public Y Y Y Y
protected Y Y Y N
no modifier Y Y N N
private Y N N N
Primarily
If you need to use it outside the class, make it public (or protected if you need it only in subclasses, or the default [no keyword at all] if you need it just in the package). If you need to use it outside the class and it's private and you can't make it not private, that's a design problem you should fix.
But...
...you can work around it using reflection (tutorial, docs), which allows you to get the method and call it even though it's private. Once you have the Method object, you have to call setAccessible to true before you call it.
But again, that's a workaround. Use the correct access modifier.
private methods are not accessible from another class by definition. If you need to call it you can create another public method that internally calls the private one or change the access modifier to public/protected/default.Example:
private static String secretMethod() { return "secret"; }
public static String knownMethod() { return secretMethod(); }
You will want to choose the proper access modifier for the method, the options are: public, protected, default (which is indicated by not providing a modifier), and private.
A good explanation is here: http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html
As mentioned in the comments, you can use public to open it up, but if you don't want such a wide access, you could start with default (which allows you to access the method if you're in the same package), or protected (which is the same as default, but also allows child classes to access the method, if you wanted to extend the class).
As a general rule, stick with the most restrictive permission. It's easier to open up permissions later, but very hard to remove them.
You can not access Private methods outside the class which defines this method. You should make it Public to give full access to any classes or protected to give access to all the classes in the same package.
Click [here] http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html For more reference.
If you really wish to access private method, you will have to use Java Reflection. See this sample code.
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Workspace {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
ClassWithPrivateMethod cwpm = new ClassWithPrivateMethod();
Method m = cwpm.getClass().getDeclaredMethod("privateMethod", String.class);
m.setAccessible(true); //This is a key statement for accessing private methods
m.invoke(cwpm, "test");
}
}
class ClassWithPrivateMethod {
private void privateMethod(String someParam){
System.out.println("I am private!!!");
System.out.println("Parameter: " + someParam);
}
}
This code will print following output:
I am private!!!
Parameter: test
Just change the visibility from private to public so other Instances can access them. Private means it is only for the own class available.
I tried to access a variable in the main class from another class. I don't know if it's possible but I need those variables. If there is a way please show me. This is the simple example.
public class A(){
public static String status;
public static void main(String [] args){
Scanner s = new Scanner(System.in);
System.out.println("Deadlock or no deadlock (y/n)");
status = s.nextline();
......
}
Then I want to use this variable "status" in another class which implements a runnable (thread). If status is "y" then a particular block of codes (if/else) inside the run methon will executes.
Anyone point me how do I call the main class so I can access the variable status from my the runner class. Thanks.
The field status in class A is public and static, so you can call it from wherever you like.
public class B {
public void myMethod() {
System.out.println("A's status is " + A.status);
}
}
A point on terminology: A here is a class, which represents an object. main happens to be a method within that class A. So you'd say that status belongs to A, not to main.
No java is pass by value not pass by reference. You could follow the example I'm linking and see if that helps though.link You could make it static and it would be usable that way but any operations on it would change when ever you perform any on it hence static.
i'm currently just fooling around with different classes to test how they work together, but im getting an error message in NetBeans that i cant solve. Here's my code:
class first_class.java
public class first_class {
private second_class state;
int test_tal=2;
public void test (int n) {
if (n>2) {
System.out.println("HELLO");
}
else {
System.out.println("GOODBYE");
}
}
public static void main(String[] args) {
state.john();
TestingFunStuff.test(2);
}
}
class second_class
public class second_class {
first_class state;
public int john () {
if (state.test_tal==2) {
return 4;
}
else {
return 5;
}
}
}
Apparently i can't run the method "john" in my main class, because "non static variable state cannot be referenced from a static context" and the method "test" because "non static method test(int) cannot be referenced from a static context".
What does this mean exactly?
Screenshot of the error shown in netbeans: http://imageshack.us/photo/my-images/26/funstufffirstclassnetbe.png/
It means state must be declared as a static member if you're going to use it from a static method, or you need an instance of first_class from which you can access a non-static member. In the latter case, you'll need to provide a getter method (or make it public, but ew).
Also, you don't instantiate an instance of second_class, so after it compiles, you'll get a NullPointerException: static or not, there needs to be an instance to access an instance method.
I might recommend following Java naming conventions, use camelCase instead of under_scores, and start class names with upper-case letters.
The trick here to get rid of the error message is to move the heavy work outside of main. Let's assume that both lines are part of a setup routine.
state.john();
TestingFunStuff.test(2);
We could create a function called setup which contains the two lines.
public void setup() {
state.john();
TestingFunStuff.test(2);
}
Now the main routine can call setup instead, and the error is gone.
public static void main(String[] args) {
setup();
}
However, the other members are correct in that your instantiation needs some cleanup as well. If you are new to objects and getting them to work together might I recommend the Head First Java book. Good first read (note first not reference) and not all that expensive.
Classes can have two types of members by initialization: static and dynamic (default). This controls the time the member is allocated.
Static is allocated at class declaration time, so is always available, cannot be inherited/overridden, etc. Dynamic is allocated at class instantiation time, so you have to new your class if you want to access such members...
It is like BSS vs heap (malloc'd) memory in C, if that helps..