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.
Related
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
In a class I have something along the lines of the following:
public class MyClass {
private static boolean running;
public static void main(String[] args) {
//setRunning(false);
//running = false;
}
public static void setRunning(boolean running) {
MyClass.running = running;
}
}
I was wondering what the most conventional way of changing the value of 'running' is, seen as I have access to using the setter method that I use in other classes, as well (somewhat)direct access to changing the variable value without calling a method.
I understand that simply doing running = false; may be more efficient (correct me if I'm wrong) but I am unsure on what the convention is for a class to change its own local variable where others would use its setter method.
I don't exactly understand what you're question is. I think you're asking how classes should alter their own variables.
If that is the case, classes should not invoke their own Getter or Setter methods for local variables, just accessing the variable directly should suffice.
Edit: this may be a stylistic thing, but I suggest using the "this" keyword in your Setter instead of "MyClass"
So instead of MyClass.runner = runner, use this.runner = runner;
If running is used outside of the class, then it has to be public static boolean running;
Inside of the class, saying running = false would do just fine.
I was wondering if anyone had a pattern that would help me achieve the following:
We have a JPA entity called Employee and on it there is a setLineManager method. We also have a separate updateLineStructureService, which is a Spring-managed service bean. We want to try and ensure that this setLineManager method can only be called from updateLineStructureService and not directly from any other class.
Is there a way to allow the service access to this method without exposing it to any other classes? I am aware that I could give the method package level access and put the service in the same package as Employee, but that will not fit our package structure so I would prefer not to do that. I am also aware that I could make the method private and just access it through reflection in this one place, but I do not like that solution at all.
Any ideas?
You can inspect the stacktrace (using Throwable#getStackTrace()) and see if it contains the allowed method on specified position.
In the following code snippet, System.PrivateEmployee is not visible outside the System class. Thus effectively privateMethod is private and can only be called from within the System class. Since System.PrivateEmployee extends System.PublicEmployee it can be used outside the System class as System.PublicEmployee
public class System
{
public static interface PublicEmployee { void publicMethod ( ) ; }
private static interface PrivateEmployee extends PublicEmployee { void privateMethod ( ) ; }
}
Use an inner class only available to the other service class:
public class Employee
{
static {
LineStructureService.registerEmployeeHelper(new EmployeeHelper() {
#Override
public void setLineManager(Employee emp, Object foo) {
emp.setLineManager(foo);
}
});
}
public static void init() {}
private void setLineManager(Object foo) { }
}
public class LineStructureService
{
private static volatile EmployeeHelper _helper;
static {
// ensure that Employee class is loaded and helper registered
Employee.init();
}
public static synchronized void registerEmployeeHelper(EmployeeHelper helper) {
_helper = helper;
}
public void doSomething(Employee emp)
{
// now this class can call setLineManager on Employee
_helper.setLineManager(emp, blah);
}
public interface EmployeeHelper {
public void setLineManager(Employee emp, Object foo);
}
}
The only way that a class can access private methods of other classes is with inner classes. If that is not an option, this can't be done.
One approach is to make two forms of Employee.
"BasicEmployee" has all the methods except setLineManager(). "ExtendedEmployee" extends BasicEmployee and adds a public void setLineManager(). (I'm assuming these are classes, but they could also be interfaces instead) Underneath the hood, everything is really a FullEmployee (for clarity, you could make BasicEmployee abstract). But, in the code, in all the classes except UpdateLineStructureService, you declare it as a BasicEmployee. Only in UpdateLineStructureService is it declared as a FullEmployee. So, only UpdateLineStructureService has easy access to setLineManager()
Now, a rogue coder could always cast their BasicEmployee to an ExtendedEmployee to access setLineManager(), so this isn't totally secure. But it's a reasonable pattern to limit access.
You could use AOP (e.g. AspectJ or CDI) to intercept the call to setLineManager(); if the caller is updateLineStructureService() call the method; if not do nothing, or raise an exception or whatever.
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..
I'm trying to initialize a static class, with an argument, and then run some more static code in that class.
I'm aware of the static block, but it seems it can't take any arguments.
Is there a way to pass arguments to a static constructor?
If not, what is the recommended technique to initialize a Static class using an argument?
Edit:
A static class to my understanding is a class which cannot be instantiated (in c# they're called static classes, if Java has a different term for them, sorry for not being aware of it) - it's accessed through it's class name rather than an object name.
What I'm trying to achieve (very simplified) is a class which receives a dictionary as String, parses it, and has methods manipulate it like GetRandomEntry.
Here's an elaborated snippet of my code:
public class QuestionsRepository {
private static Map<String,String[]> easyDefinitions = new HashMap<String,String[]>();
//...
staticĀ
{
// need to receive and parse dictionary here
}
//...
Taking the relevant parts of a code snippet is never easy, hope i have chosen wisely (:
Another detail that may be relevant - I'm a c# programmer, usually. Just Started learning Java lately.
Thanks.
I think you would need to initialize the static fields of the class according to some input. You can do it in the following way by calling the static method of another class:
class ClassToInitialize {
static {
staticField = ParamPassClass.getParameter();
}
private static String staticField;
ClassToInitialize() {
System.out.println("This is the parameter: " + staticField);
}
}
class ParamPassClass {
private static String parameter;
static String getParameter() {
return parameter;
}
static void setParameter(String parameter) {
ParamPassClass.parameter = parameter;
}
}
class Main {
public static void main(String args[]) {
ParamPassClass.setParameter("Test param");
new ClassToInitialize();
}
}
Java doesn't have static constructors. It only has static initializers and static initializers do not take any arguments. It is executed when the class is first loaded, and there is no way to call it yourself.
You either need to use actual objects, or add some way of configuring the class (eg through a static method).
you should mention the member class with a static qualifier, otherwise there is no such a thing as a static class
Here you can find the explanation of using the word 'static' in this context.
Now you should just call its constructor and pass all the arguments you want,
the only restriction that you have on a static member class is that it can't refer the non-static fields of its outer class, it resembles a static methods on class that can't refer the non-static fields of class.
I didn't understand why do you mention a static initialization block here, could you please clarify a little?
Be aware also that in java there is no such a thing as static constructor....
Hope this helps
You can have a static method public static void setUp(Arg1 arg1, Arg2 arg2...) which sets up all your static fields and invoke it when your program starts.
You have to make sure this method will be called only once [or only when you want to reset these fields]
It is not possible to pass arguments directly to the static initializes (JLS:static initializers).
It would be nice if you could share more information about your goals.
You could use an enum to initialize a singleton with a string parameter like this
import java.util.*;
class Data {
static Map<String,String[]> easyDefinitions = new HashMap<String,String[]>();
}
public enum QuestionsRepository
{
repository("primary=red,green,blue;secondary=cyan,yellow,magenta");
QuestionsRepository(String dictionary) {
String[] rules = dictionary.split(";");
for (String rule:rules) {
String[] keyValuePair = rule.split("=",2);
Data.easyDefinitions.put(keyValuePair[0],keyValuePair[1].split(","));
}
}
}