public class A
{
public static void main(String args[])
{
}
}
class B
{
private static void call
{
int x=9;
String name ="hello";
}
}
Can anyone please tell me how to access class B private method fields in class A and print them in class A.
Thank u..
You can access private fields and methods in other classes, but the whole point is that you're not supposed to. They're private.
So the correct thing to do is make them available to other classes by making them public. In the case of fields (rather than methods), you might do that with accessor methods.
But, if you really had to access private fields or methods, you can do it via java.lang.reflect.
// Calling the static `call` method of `B` even though it's private:
Method m = B.class.getMethod("call");
m.setAccessible(true);
m.invoke(null);
But again, you shouldn't do this without a really good reason. Fix the design instead.
We Should Not try to access directly the private members of a class in another class. This will altogether violate the rule of Access Modifiers. Moreover if you really want to access, you can make use of Reflection API provided.
Generally, in order to get the private class variables, you can create public setters and getters in order to access then outside that class.
By design you cannot. Revise the class so the method you want to call is visible to A.
That said, you can use reflection to access methods, fields etc inside B, but you cannot easily just do it with "B.call()" which most likely is what you would like to do.
Related
I wonder if it's okay (not considered bad practice) to have public members in package private class. I tend to add public keyword to members of my default visibility classes to indicate that such members are part of the classes API.
I do it only for readability, since in this case public members have essentially the same visibility as members without any access modifiers (i.e. package visibility). Is that correct?
Example:
class ModuleImplementationClass {
private int fieldA;
private String fieldB;
private void someClassInternalMethod() {
// impl
}
public int doSth() {
// method that will be called by other classes in the package
}
}
I do it only for readability, since in this case public members have essentially the same visibility as members without any access modifiers (i.e. package visibility). Is that correct?
Well that depends. Not if you're overriding existing methods (e.g. toString()) or implementing an interface.
If you don't want the method to be used from outside the package, make it package private. If you're happy for it to be used from anywhere, make it public. Or another way to think about it: design your method access so that if someone changed just the class access to make it a public class, you wouldn't want to change the method access too.
We can access Private data members using accessor method such as
private int num=5;
public int get_num()
{
return num;
}
and we can access the returned value from any class even though num is private data member.
So on Similar note cant we create accessor method that returns private methods?
I just had a thought about it,If we cannot do this please explain.Thank You
Private methods are created when refactoring your code. They are implementation details, which nobody outside needs to know. They are used inside public methods, which are supposed to provide the functionality you want to provide to your client(each public method can be called an API which is used/consumed by other classes i.e. its clients).
Access modifiers are provided to help you achieve proper abstraction. So anything marked private is directly accessible only inside your class. But if you want someone outside to read/write its value, you expose it via getters/setters. Similarly private methods are not accessible outside the class. But nobody is stopping you from creating public method that only calls this private method. This way you do achieve access to private method. But it would be a very poor design.
You can access private method via public method. This is sometimes used to wrap complicated private method and expose simpler, public API.
class Delegator {
private void doPrivateStuff(int param) { ... }
public void doStuffOnce() {
doPrivateStuff(1);
}
public void doStuffIfConditionIsMet() {
if(condition) {
doPrivateStuff(1);
}
}
}
You can also access private methods using reflection.
http://tutorials.jenkov.com/java-reflection/private-fields-and-methods.html
Because the accessor is public, it can be accessed from outside the class; even if it returns private data.
The access modifier of the returned data isn't relevant, only the access modifier of the method matters.
If you created a public method that returned a reference to a private method, yes, you could then call the private method from outside the class. That would entirely defeat the purpose of making the method private however.
You my be wondering "why make a public getter to a private variable". The answer is that although it's possible to retrieve the private data, it isn't possible (unless you create a public setter as well) to change the public data. This assumes that the private days is immutable. If it's mutable, retuning a reference to private data negates any protection you get from making the variable private.
TL;DR
Accessing private methods violates the basic object oriented principle of encapsulation. The question is not "can we access a private method?" but "should we ever do it?". It contradicts the principle of information hiding and it breaks the contract an object "offers" to its consumers. Objects or classes that enforce you to do that should be considered poorly designed.
Why you shouldn't access private members
First a classes should implement a part of your domain logic that is so closely related that there are little interactions necessary with the outside world to fulfill its duties (this is called high cohesion). You then define a public interface for your class / object with functionality that you expose to the outside world - consumers of your object must only use this interface (this is called loose coupling).
Private methods can be seen as a way to structure your code inside your class in a better readable way - they are not intended to be shared with the outside world. Consider them as a "safe space" for the developer of the class to make arbitrary changes without breaking the contract. That's the reason why there can be bad side effects if you actually access private methods: your code is likely to break it the developer of the class decides to change the implementation of such a method. Effective Java, Chapter 4, Item 13 explains this for protected members:
For members of public classes, a huge increase in accessibility occurs when the access level goes from package-private to protected. A protected member is part of the class's exported API and must be supported forever. Also, a protected member of an exported class represents a public commitment to an implementation detail.
Exceptions
The only exception I know from the rule of "not accessing private members outside of an object" is in testing, when you either want to reset a certain variable (e.g. a Singleton) or you want to facilitate the testing of complex logic by testing the private parts of the implementation and hence reducing complexity in testing.
I wonder if it's okay (not considered bad practice) to have public members in package private class. I tend to add public keyword to members of my default visibility classes to indicate that such members are part of the classes API.
I do it only for readability, since in this case public members have essentially the same visibility as members without any access modifiers (i.e. package visibility). Is that correct?
Example:
class ModuleImplementationClass {
private int fieldA;
private String fieldB;
private void someClassInternalMethod() {
// impl
}
public int doSth() {
// method that will be called by other classes in the package
}
}
I do it only for readability, since in this case public members have essentially the same visibility as members without any access modifiers (i.e. package visibility). Is that correct?
Well that depends. Not if you're overriding existing methods (e.g. toString()) or implementing an interface.
If you don't want the method to be used from outside the package, make it package private. If you're happy for it to be used from anywhere, make it public. Or another way to think about it: design your method access so that if someone changed just the class access to make it a public class, you wouldn't want to change the method access too.
Sometimes when writing a class you'll need some helper methods that take care of some simple stuff (change a string in a certain way or do some simple calculations).
If helper functionalities are small enough (and not needed by any other class) it makes sense to write a helper method in this class.
Now: assuming you'll need no access to any member variables, would it be better do make this method private or private static
the following example: just implements a method that checks if a string is not null and contains foo.
public class SomeClass
...
public void calculate(String inputString) {
...
boolean foo = getFoo(inputString);
}
private (static) boolean getFoo(String inputString) {
return inputString != null && inputString.contains("foo");
}
}
Are there pros and cons in making the method static or non-static. Is there a general do and don't?
I would personally make the method static - it makes it clearer that it doesn't depend on the state of the object. That can have knock-on effects in terms of thread safety (although if it were to access static members of the type, you'd need to be careful of that).
Given that it's private, you don't need to worry about whether or not subclasses would want to override it.
You can always make it non-static later - I think the only side-effect of that would be to potentially change the serialization ID. (Binary serialization is a pain like that.)
Make it non-static if it needs access to non-static member variables, and make it static if it doesn't.
Is the private member access at the class level or at the object level. If it is at the object level, then the following code should not compile
class PrivateMember {
private int i;
public PrivateMember() {
i = 2;
}
public void printI() {
System.out.println("i is: "+i);
}
public void messWithI(PrivateMember t) {
t.i *= 2;
}
public static void main (String args[]) {
PrivateMember sub = new PrivateMember();
PrivateMember obj = new PrivateMember();
obj.printI();
sub.messWithI(obj);
obj.printI();
}
}
Please clarify if accessing the member i of obj within the messWithI() method of sub is valid
As DevSolar has said, it's at the (top level) class level.
From section 6.6 of the Java Language Specification:
Otherwise, if the member or
constructor is declared private, then
access is permitted if and only if it
occurs within the body of the top
level class (ยง7.6) that encloses the
declaration of the member or
constructor.
Note that there's no indication that it's restricted to members for a particular object.
As of Java 7, the compiler no longer allows access to private members of type variables. So if the method had a signature like public <T extends PrivateMember> void messWithI(T t) then it would be a compiler error to access t.i. That wouldn't change your particular scenario, however.
Note that you don't even need source level access to mess with private fields. By using java.lang.reflect.AccessibleObject.setAccessibe(), all code can access all private members of all other code unless you specify a security policy that disallows it.
private is not by itself a security feature! It is merely a strong hint to other developers that something is an internal implementation detail that other parts on the code should not depend on.
Neither. Private access is scoped to the enclosing top-level class, so you can access private members of different class in the same top-level class:
class PrivateAccess {
static class InnerOne {
private int value;
}
static class InnerTwo {
int getOne ( InnerOne other ) {
return other.value;
}
}
}
The usual meaning of class access means that you have access to privates of other instances of the same type. In Java, private access is determined lexically, not by type.
Class level. The idea is that the code of a class (but nothing else) knows how to handle objects of that class.
If you have access to the class source code anyway, there is little sense in "hiding" anything from you.
As others have stated, private, default access ("package private"), protected and perhaps in JDK 7 module are class based (there are very strange rules for nested classes inheritance that I can't remember). But why?
Primarily it's down to methods that act as binary (or more) operators. For efficient implementation they often require or are easier to write without having to use or modify the public API. Have a look through at implementations of equals - in good code you'll find direct access of fields with few method calls to this. (The performance aspect of this is now mostly irrelevant with modern JVMs inlining common calls, but the code quality issue is still there.)
Just to add to DevSolar's answer, I would expect messWithI to be declared static as such:
public static void messWithI(PrivateMember t) {
t.i *= 2;
}
I had a hard time even reading what it is that you were trying to do without the 'static' hint... And it also makes it easier to answer your original question -- which is that private members are not limited in scope to just the instance in question.
The same page says, in sub-section 6.6.8, you can also find the following statement:
A private class member or constructor is accessible only within the body of the top level class that encloses the declaration of the member or constructor. It is not inherited by subclasses.
The private class member whose access we evaluate here is i.
public void messWithI() is a method that exists within the body of the top level class where i has been declared, which is, precisely, PrivateMember.
Your construct meets the statement above, and that is why it runs without problems.
Thas is another way to say the same as Jon and Devsolar.
Access modifiers for class members are related to where the code is written, (in which package, and in which class), regardless of what kind of member the access gets granted: a class member or an instance member.
Logically, you cannot use an instance member of a class if you do not have an instance of the class, but that is a different issue, related to the life-cycle of the member.