I've recently started learning Java using JDK1.6. If this is a silly question, please excuse me.
If private variables can be directly accessed by objects in main() how are they 'private'?
public class Account1
{
private int accountNum;
private String name;
Account1() {
accountNum = 1101;
name = "Scott";
}
public void showData() {
System.out.println("Account Number: " + accountNum +
"\nName: " + name);
}
public static void main(String[] args) {
Account1 myA1 = new Account1();
myA1.showData();
System.out.println(myA1.accountNum); //Works! What about "Private"?!
}
}
Which gives the output:
Account Number: 1101
Name: Scott
1101
Your main is in the Account1 class, so it's still in the same scope.
Private variables can be accessed from any code belonging to the same type. If your main method was in a separate class then it wouldn't be able to access them (without using reflection).
The "main" method of a given class is part of that class. Methods that are part of a class have access to private members of that class. That makes sense to me. Doesn't necessarily mean you should use it, of course.
One way to think about it is to think about one class's knowledge of another class's internal workings. My Person class shouldn't know what happens inside my Order class; it just calls public methods on it. But anything inside Person will of course know about the internal structure of Person -- even a different instance of Person.
This is because the main() function is a member of the class. It has access to all members of the class.
In real world code, the main function is usually situated in a "harness" class that actually bootstraps the rest of the code. This harness class is usually very lightweight and instantiates other classes that do the real work.
They are private in that they can only be accessed by that class. This means they are accessible from static methods of that class (such as main) and also from instance methods (such as showData).
One instance of the class can also access private members of another instance of the class.
If you had a separate class, say, Account2, it would not be able to access provate members of Account1.
Related
I am creating an application in VBA for my employer (and a similar one in Java for hobby purposes) and its purpose is to 'contain' different tools that will help in our daily work. It's going to be some kind of platform with the main app window and from there a user can access some of the application components like for instance a sub-program when a user can give me feedback on application's functionality, then the info will be stored in a database that I can access later.
I already have a structure: an Application class, that contains the Application Manager and this one class contain an array of fields of the SubApp type. A SubApp type contains view, logic, and business of a sub-application. The Application class also contains members like the name of the app and the information about the user that is currently using the app (previously accessed from the application database).
Whenever a sub-app launch, I would like to put on the title bar the name of the app as well as the name of the sub-app, something like application_name - sub_app_name. The problem is, that I have no idea how can I access it the 'right way'. Recently I've achieved this by creating the app variable as a global object, then accessing it is no problem using some getters. I feel however that storing an application variable as a global variable is a bad practice.
The same problem occurs with the member variable storing info about the current user. I'd like to store the information about the current user while he's giving feedback (tool for giving a feedback is a sub-app in my application)
So here is my question: how can I access the methods/variables of a wrapping object from within one of the member methods/variables?
Any suggestions regarding the overall design of the application would also be welcome.
Object oriented design: use getters and setters for all fields is proper practice. If you want to be lazy, make all your fields public and they will be accessible from the object without getters or setters.
If you wish to access a variable throughout multiple methods in a class.
A) You'll can make a variable global
B) Create a local variable, and pass it as a parameter until you no longer need to use it.
public class Main { //All implementations stated above
private Object globalObject;
public static void main(String[] args) {
Object localObject;
method1(localObject);
method2ThatUsesGlobalObject();
}
}
Accessing variables between classes:
A) Make a variable static
B) Pass it through method parameters, or constructor parameters
C) Use abstract classes or interfaces
Here are examples of the code usage I've stated
public abstract class JavaAbstractClass {
public abstract Object giveMeThisObjectWhenINeedItThanks();
}
public interface JavaInterface {
Object giveMeThisObjectWhenINeedItThanks();
}
public class Main { //All implementations stated above
public static Object object; //Accessible by Main.object everywhere
public static void main(String[] args) {
Object local;
ClassOne class = new ClassOne();
class.method1(local);
new ClassWithInterface() {
#Override
public Object giveMeThisObjectWhenINeedItThanks() {
return local;
}
};
new JavaAbstractClass() {
#Override
public Object giveMeThisObjectWhenINeedItThanks() {
return local;
}
};
}
}
Hi I am trying to access a public object in another package within a project.
I am trying to access the 'opponent' object which is of type 'Character' in the Attribute class.
public class Engine {
public static Character opponent;
}
Class I am trying to access object in. "This class is in another package".
public int opponentAttackDamage() {
int attack = opponent.getAttribute().getAttack();
}
In order to access an static attribute from anywhere even in the same class where it's declared (as a good practice) you should use the name of the class follow by dot an the name of the attribute:
Engine.opponent.getAttribute().getAttack();
Also you should have in mind that opponent object must be initialized in somewhere in your class (opponent = new Opponent() - I guess - ).
If opponent is a static attribute of the Engine class, and the method you are accessing it from is not in the same class, you need to mention Engine.opponent to access it. Also, you need to import the package where Engine class is defined.
class TestMemberOuter1{
private int data=30;
class Inner{
void msg(){System.out.println("data is "+data);}
}
void display(){
Inner in=new Inner();
in.msg();
}
public static void main(String args[]){
TestMemberOuter1 obj=new TestMemberOuter1();
obj.display();
}
}
Why innerclass is able to access private members of the outerclass ?
I want to know what implementation [ at the lower level (Maybe at memory level or java implementation specific or any other not sure)] enables to achieve this kind of behaviour in java .
I dont think neither you need any memory level modifictaion or logic implementation to achieve this nor I think java will have any huge code logic at memory level to implement the same.
Memory has got nothing to do with it. Private, public and protected are just a access filters, No matter whether it is a private, public or protected all these variables will reside in a same memory which is allocated for an object.
There is no differrent memory allocation for private, public or protected variables. They are all ultimately the properties of same object.
Then how come compiler handles this ???
Its bit simpler than that.
These access filters clearly informs in what context they should be allowed to access.
Private : Only whitin the class :) Whenever compiler sees the variable which is provate being accessed any where out side the class it will flag the error Thats all.
Protected : All class within the same package :) Whenever compiler sees the variable which is Protected being accessed any where out package it will flag the error Thats all.
Public : Access to all :) No flags.
Remember accessing variables outside context results in compiler error not runtime error ?? For the same reason.
You dont need a huge logic behind it, Just keep the list of private, protected and public variables and check their usage is appropriate or not thats all.
EDIT
As per your updated question "Why innerclass is able to access private members of the outerclass ?"
Drawing the conclusion from the same analogy I explained above, private variables are allowed to be accessed anywhere within the class.
Now where is your innerclass declared? As a part of your outer class itself isn't it. So when you access the private variable of outer class inside the inner class compiler has no issue with it, because your inner class itself resides inside the outer class.
I hope I made a little sense with my answer :) Happy coding.
Currently, inner classes are compiled into distinct class files, but the compiler will insert synthetic helper methods when there is an access to a private member across nested classes. The synthetic method itself will have package-private access and perform the access to the private member within its own class.
This can be demonstrated with private methods as their execution can be traced and will show the execution of these helper methods:
public class OuterClass {
static class InnerClass {
private static void test() {
OuterClass.privateMethod();
}
}
private static void privateMethod() {
Thread.dumpStack();
}
public static void main(String[] args) {
InnerClass.test();
}
}
Running this program will print:
java.lang.Exception: Stack trace
at java.lang.Thread.dumpStack(Thread.java:1329)
at OuterClass.privateMethod(OuterClass.java:9)
at OuterClass.access$000(OuterClass.java:2)
at OuterClass$InnerClass.test(OuterClass.java:5)
at OuterClass$InnerClass.access$100(OuterClass.java:3)
at OuterClass.main(OuterClass.java:12)
These nested classes are compiled into two distinct class files OuterClass.class and OuterClass$InnerClass.class. You can see that the compiler has inserted the synthetic method access$100 into OuterClass$InnerClass which allows the main method of OuterClass to invoke the private method test of the inner class. This inner class method in turn invoked a synthetic method access$000 in the outer class which allows the invocation of privateMethod() in OuterClass.
Note that this kind of access is different to the access to private members performed with Java 8’s lambda expressions and method references. For the member access performed in that context, no helper methods are generated by the compiler and the way the JVM makes the access possible is intentionally unspecified, but we can say that for Oracle’s current JRE implementation, there will be a runtime-generated class which is indeed capable of bypassing the access restriction of private members, e.g.
import java.util.function.Consumer;
public class OuterClass {
static class InnerClass {
static final Consumer<Runnable> TEST_METHOD=InnerClass::test;
private static void test(Runnable outerMethod) {
outerMethod.run();
}
}
private static void privateMethod() {
Thread.dumpStack();
}
public static void main(String[] args) {
System.out.println(System.getProperty("java.version"));
InnerClass.TEST_METHOD.accept(OuterClass::privateMethod);
}
}
As of 1.8.0_65, it prints:
java.lang.Exception: Stack trace
at java.lang.Thread.dumpStack(Thread.java:1329)
at OuterClass.privateMethod(OuterClass.java:12)
at OuterClass$InnerClass.test(OuterClass.java:8)
at OuterClass.main(OuterClass.java:16)
Not showing such helper methods, but also filtering out the runtime-generated classes. Changing privateMethod() to
private static void privateMethod() {
for(StackTraceElement e:Thread.getAllStackTraces().get(Thread.currentThread()))
System.out.println("\tat "+e);
}
reveals
at java.lang.Thread.dumpThreads(Native Method)
at java.lang.Thread.getAllStackTraces(Thread.java:1603)
at OuterClass.privateMethod(OuterClass.java:12)
at OuterClass$$Lambda$2/135721597.run(Unknown Source)
at OuterClass$InnerClass.test(OuterClass.java:8)
at OuterClass$InnerClass$$Lambda$1/471910020.accept(Unknown Source)
at OuterClass.main(OuterClass.java:16)
with the generated classes having fancy names like OuterClass$InnerClass$$Lambda$1/471910020 and OuterClass$$Lambda$2/135721597 which are accessing the private members. Note that the generation of these classes has been triggered by the classes which have the right to access these private members, which has been checked before allowing to create such function objects.
This question already has answers here:
Understanding Java's protected modifier
(6 answers)
Closed 7 years ago.
I am in process of learning the Java access modifiers. For that, I have created a class Machine:
package udemy.beginner.interfaces;
public class Machine {
public String name;
private int id;
protected String description;
String serialNumber;
public static int count;
public Machine(){
name = "Machine";
count++;
description = "Hello";
}
}
Then, in another package, I have created a class Robot as a subclass of a car Machine:
package udemy.beginner.inheritance;
import udemy.beginner.interfaces.Machine;
public class Robot extends Machine {
public Robot(){
Machine mach1 = new Machine();
String name = mach1.name;
//here I am getting error "The field Machine.description is not visible"
String description = mach1.description;
}
}
I am getting an error when trying to access the field description in the class Robot. From my understand of how protected access modifier works, it should be OK though, but maybe I messed up something. Any thoughts?
EDIT: I have tried to move Robot class to the same package as Machine class is in and now it works, without a need to use this. If someone can explain me this. According to the answers below, it should not work as well ...
You can't access a protected superclass field in a different instance of the class.
There's a good reason: you don't know whether it has the same subclass as yourself, or a completely different subclass. If it were allowed to access the protected field, you would be allowed to access the internals of entirely unrelated classes.
If you are sure that the object is of the same subclass as the class that wants to access the superclass field, you can cast the object; when you that, you can access the protected field.
The rules are described in the Java Language Specification section 6.6.2
6.6.2. Details on protected Access
A protected member or constructor of an object may be accessed from outside the package in which it is declared only by code that is
responsible for the implementation of that object.
6.6.2.1. Access to a protected Member
Let C be the class in which a protected member is declared. Access is
permitted only within the body of a subclass S of C.
In addition, if Id denotes an instance field or instance method, then:
If the access is by a qualified name Q.Id, where Q is an
ExpressionName, then the access is permitted if and only if the type
of the expression Q is S or a subclass of S. [This is the relevant section]
protected variables are accessible outside class, but only through inheritance. So, if you change that statement to this:
public Robot(){
Machine mach1 = new Machine();
String name = mach1.name;
// This will work (access on `this` reference)
String description = this.description;
}
Actually protected modifier means that, the field is visible to be inherited by the subclasses, and it can be used only there, using this reference.
I'm trying to create an object (LineItem), and then create variables of that object. I want to create a 'cookie' that has a price, a name, and a quantity assigned to it. My problem begins at cookie.price = 5, my IDE tells me that 'package cookie does not exist.' I am very confused. It gives me the same error whether or not I declare cookie outside of the LineItem class.
public static void main(){
public class LineItem{
int price;
String foodName;
int quantity;
LineItem cookie = new LineItem();
cookie.price = 5;
}
}
In Java, you cannot directly write the executable statements in class.Only variables declaration is allowed outside the method/blocks/constructor
You need to move the code cookie.price = 5; into a method/constructor/block.
Put it into a method. You have not got a main method and your program cant start this way. No research done. Use proper syntax and learn the basics. To refer to the class use the this keyword. You shall not create an instance of the class again in the same class. Instead of using this.variable you can refer to the variable straightforward if it is in the same class declared outside of any methods