How to access a non-static private field in java? - java

I have a non-static private field in a package and want to access it from another package but I don't know how to do that. I searched but I didn't find anything useful and other questions in this site weren't exacatly my question.

The only way you can do this is via reflection. But it's a hack. You really ought to be finding another way round it.
If you need to do it, then it suggests that the other package has a badly designed structure. If the class you're trying to manipulate is one of your own, you should look at changing that code.
If you really need to do it and you can't change the other class, you do it with something like this:
Field f = BadClass.class.getDeclaredField("privateField");
f.setAccessible(true);
f.set(badClassInstance, newValue);
Probably the best places to start are a tutorial on reflection, and the setAccessible method.

Create getter and setter methods for the private fields.
example:
public void setName ( String name )
{
this.name = name;
}
public String getName ()
{
return this.name;
}

You should import the package where that non-static private field is.
If you want to access this field from subclass which is in a different package you can change "private" modifier to "protected", this will allow all packages in the same project access this field through inheritance.

Related

How could private modifier guard the encapsulation of an object, not class?

In Java, I understand why we define the instance field as private in some class, that is for protecting the encapsulation of a class. However, I am confused about the instance of that class. See below:
public class DotaHero {
private String name;
...
}
Till now, any outer class could not use the name directly! Then,
DotaHero zeus = new DotaHero();
zeus.name = "Zeus";
That is legal in Java. However, anyone who hate me would change my code easily, like:
zeus.name = "Chick";
Then, when I use object zeus to invoke the "zeusWrath" skill, it will show a script on screen, "The Chick is Furious!".........
Maybe someone would argue I was supposed to use setter method to define the name, and configure some checking mechanisms inside. However, my opponent still could directly access the name by zeus object.
I am sure I am misunderstanding something, but I can't find it...

How to inherit a private variable in Processing?

[I know the following does not respect OOP rules, this is an early-dev project. I will do all the setters and getters later]
I have a class called 'Item', which contains a private field 'name'.
abstract class Item{
protected PImage texture;
protected int durability;
protected int maxDurability;
private String name;
}
I also have a class called 'Armor', which inherit 'Item'. So it should inherit the private field 'name', right ?
class Armor extends Item{
protected int defense;
Armor(){
//First try to change the value
name = "Armor";
//Second try using 'this' to be sure it doesn't try to change super.name
this.name = "Armor";
}
}
In both cases, I have an error when I try to change the value : "The field Time_Fighter.Item.name is not visible".
After reading some stuff about how 'private' works in Processing, I discovered some people proposed to use 'protected' instead.
The thing is, if I use 'protected', every classes have access to it. But I just want 'Item' and the subclasses of 'Item' to have access to their private fields inherited from 'Item'.
I might have done a pretty obvious error since I'm kinda just a beginner, so if this is not the intended way of doing so, please tell me how I'm supposed to do it...
[Edit.
It seems from answers I've seen that this is not possible this way. So here's there any way to have a variable that would only be accessible for subclasses and not all the package ?]
You can't.
Private variables are just that: private. That means a subclass can't access them.
You might instead add a setter() function that the subclass uses.
Normally you would just make it protected, but Processing doesn't use packages, so it ends up being the same as public.
Honestly, I wouldn't worry too much about this. Processing is designed to make things simple, so it skips over this topic a bit. If you really want this functionality, you might consider writing Java code (which can call Processing code), but that's a lot more involved than just writing Processing directly.
In your case, you might create a constructor in your Item class that takes a name as a parameter. Then you can call that constructor from your Armor class and pass in whatever value you want:
abstract class Item{
private PImage texture;
private int durability;
private int maxDurability;
private String name;
public Item(String name){
this.name = name;
}
}
class Armor extends Item{
private int defense;
Armor(){
super("Armor");
}
}
You can make your name field protected and place your Item and Armor classes to a separate package. Fields declared as protected are available to the classes of the same package and descendant classes.
See Controlling Access to Members of a Class
you can access all class-global variables even private ones via Reflection How do I read a private field in Java? . I use this a lot and it works pretty fine. So if someone really wants to access the variables he can most of the time.

Accessing protected variables in the super class

I have recently joined a new company and I am trying to get used to their coding style guidelines. I have no problem changing my coding style, but one particular point, I am not sure whether they are right or not.
For my first task I had to extend one of the existing abstract classes to develop a particular functionality. Thus I needed to access many attributes declared in this abstract superclass. To do so I proposed to change the visibility of these attributes and declare them as protected. My surprise came with their reply:
"Never! That is absolutely against OOP and you would produce obscure and difficult to maintain code! What you have to do is creating a getter in the super class and using it from the subclass in order to access these attributes".
Well, I have been always using protected attributes in an abstract superclass and accessing them from the subclass directly and I always thought there was nothing wrong with it. Even I would say that calling all the time the getter to access an attributes in the super class is slower than using it by its name...
What do you think about it? Is it normal/standard coding style declaring the attributes in a superclass and accessing them directly or are you of the oppinion that is better creating getters for these attributes.
To sumarize, my way:
public abstract class A {
protected String variableA="a";
public abstract methodToImplement();
}
public MyClass B extends A {
public methodToImplement() {
System.out.println(variableA.length());
}
}
Their way:
abstract class A {
protected String variableA="a";
public String getVariableA() {
return variableA;
}
public abstract methodToImplement();
}
MyClass B extends A {
public methodToImplement() {
System.out.println(getVariableA().length());
}
}
Thanks.
So as other threads already point out it appears to be so that it's indeed recommended to use getters and setters. The reason being that if you ever plan to change the representation of that value (StringBuilder instead of String for example) you will have to change your code. A getter/setter allow you to program in a way that you send the getters/setters the data you want, and they will store it in the proper field for you (e.g., appending it to the StringBuilder). So yes, it apears to have a lot of advantages, even though it's not your coding style. However, declaring the variable as protected seems pretty weird when you use a getter and a setter as well..
I personally try to avoid getters/setters when they are a bit of overkill. To me they are overkill for value variables. For reference variables they are however a good idea.
However, I think there is no right or wrong here..

using a variable in two different java classes

I was wondering if it's possible to use a variable of a java class in another java class.Suppose variable Time is defined and calculated in Class A, how can I use it in Class B?
Other answers have suggested increasing a variable's visibility. Don't do this. It breaks encapsulation: the fact that your class uses a field to store a particular piece of information is an implementation detail; you should expose relevant information via the class's API (its methods) instead. You should make fields private in almost all cases.
Likewise, some other answers have suggested possibly making the variable static. Don't do this arbitrarily. You need to understand what static really means: it's saying that this piece of information is related to the type rather than to any one particular instance of the type. Occasionally that's appropriate, but it's generally a road towards less testable code - and in many cases it's clearly wrong. For example, a Person class may well have a name variable, but that certainly shouldn't be static - it's clearly a piece of information about a single person.
You should think carefully before exposing information anyway - consider whether there's a wider operation which the class in question could expose, instead of just giving away its data piecemeal - but when you do want to expose a field's value, use a property. For example:
public class Person {
private final String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
By exposing it via a method, you can later change the implementation details without breaking existing clients.
Then from another class, you'd just call the getName() method:
// However you end up getting a reference to an instance of Person
Person person = ...;
String name = person.getName();
If you do have a static field, you can expose the value in the same way, but with a static method, which you'd call using the class name.
Be careful about returning values which are mutable, e.g. java.util.Date. This is another reason for using a getter method instead of allowing direct access to the field - you can make the method return a defensive copy where you need to.
If it is declared as public, you may use ClassA.yourVariable. On the other hand, for private access modifier, include the getter to your ClassA. On the ClassB, call ClassA.getYourVariable().
Also read about access specifiers in Java it might help.
If the variable is static, you can refer to it as A.Time from any code that has access to the variable. There's only one Time value for all of class A. If it is an instance variable, and you have an instance a of class A, you can refer to the variable as a.Time. There's a separate value for each instance of class A.
This is subject to Java's access rules:
if the field is public, any code can access it (this makes public variables kind of dangerous unless they are also declared final)
if the field is protected, only code in the same package or in a subclass of A can access it
if the field has default access, only code in the same package as class A can access it
if the field is private, only code in class A (including inner classes of A) can access it.
Alternatively, you can provide an accessor method in class A:
public class A {
. . .
public class getTime() {
return this.Time; // the "this." is optional
}
}
If you declare your Variable as public or static you will be able to access it from another class.
WHICH IS A VERY VERY BAD IDEA :)

Confused with Java Encapsulation Concept

Good day!
I am reading a Java book about encapsulation and it mentioned the getter and setter method.
I've read that to hide the attributes, I must mark my instance variables as "PRIVATE" and make a "PUBLIC" method of getter and setter to access the data. So I tried making a similar but not the conventional code about it as follows:
public class AddressBookEntry {
private String name;
private String address;
private String telNo;
private String email;
public void getAllInfo() {
name = JOptionPane.showInputDialog("Enter Name: ");
address = JOptionPane.showInputDialog("Enter Address: ");
telNo = JOptionPane.showInputDialog("Enter Tel. No: ");
email = JOptionPane.showInputDialog("Enter Email Address: ");
}
}
Does my code above exposes my variables because I assigned it directly? How can I do this better? Would it be better if I make the conventional getter and setter method instead and assigned the values on the other class? What does "hiding the data" means?
Thank you.
You use setters and getters to make the variables accessible from outside your class. In your example you will have
public class AddressBookEntry {
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
You will access the name property from a UI class (it isn't good to mix UI and business logic in the same class):
public class MyPane extends JFrame {
public getAllData() {
String name = JOptionPane.showInputDialog("Enter Name: ");
AddressBookEntry entry = new AddressBookEntry();
entry.setName(name);
// You can't use entry.name = name
}
}
Yes and no. The point of encapsulation is that it prevents other classes from needing to know what your class is doing behind the scenes. If you store your name in a String (as you've done here), read/write it from a file, or do something different, the point of encapsulation is that to the user of your class it doesn't matter because all they see is String getName( ) and void setName (String name).
Since the modification of the data is entirely under the control of your class here, it doesn't break encapsulation. If you did store name to file, then you could potentially do so in getAllInfo without any other user of the class being any the wiser. Since the observable behaviour from the outside of the class still hides what the internals of the class is doing, it's still encapsulated.
That said, this is a very unconventional approach. Like I describe in the first paragraph, use of accessor methods (getters and setters) is a more idiomatic approach, and easier to understand for someone else using your code. You can do what you do, it doesn't break encapsulation, but it's not what I'd call elegant or typical.
The idea of private class members (attributes, fields) is to access them directly inside the declaring class (not instance!) only. All other classes will have to use other accessors, for example getter and setter methods. So the way how the AdressBookEntry stores the name, address, telNo and email values, is perfectly hidden inside the class.
You don't have to use getters or setters, although, sometimes there are good reasons to do so inside the class too. Using getters and setters sometimes makes sense if you do some logging or validating before a value is set.
This doesn't violate encapsulation, as it doesn't expose the internal data to another class. You may wish to look at Model-View-Controller (MVC) though to help separate out your interface from your data.
Traditional you create a single getter and setter for each variable as needed like so:
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
Don't create getters for variables that won't need to be accessed outside of the class, and don't create setters for variables that won't need to be set outside of the class.
If following MVC and using the traditional getters and setters like above, you would have the view code elsewhere and call something like
myAddressBookEntry.setName(JOptionPane.showInputDialog("Enter Name: "));
I agree with all the great answers provided. I would like to add another great benefit about using encapsulation and is the fact that by hiding the data from its clients (just as the examples described above) you can guarantee how to set and get these instance variables making your class easier to maintain and test (i.e if you have many clients manipulating your objects variables you don't need to go class by class writing the new functionality, instead you just modify the getter and setter).
By making usage only of the objects setters and getters, the details of its implementation can be hidden from the outside world. This is a nice advantage so other objects attempting to interact with your class won't be able to break its functionality. This also increases the likelihood that a system will be implemented effectively.
I find the answers above already answering your question. But, I see another issue with your code, which is, a security and data integrity issue. You are filling your class member directly out of the user's input w/o any validations on it. For example, you'd probably want to check that the email address has an xyz#abc.com pattern. A malicious user might also provide a very long string in the input causing unexpected errors.

Categories

Resources