I have the following code for my class, with one parameter:
public class StudentChart {
public StudentChart(int[] Results) {
int[] results = Results;
}
How can I use results elsewhere in the class? I had assumed that variables and arrays declared in the constructor were global, but apparently not.
Also, what is the purpose of using the constructor to store data if it's not global?
You should check out some articles on scope in Java.
Instance Variables
Variables defined within in a class itself and not in a constructor or method of the class.They are known as instance variables because every instance of the class (object) contains a copy of these variables. The scope of instance variables is determined by the access specifier that is applied to these variables.
public class StudentChart{
//instance variable private is the "access modifier" you can make it public, private protected etc.
private int[] results;
Argument Variables
These are the variables that are defined in the header of constructor or a method. The scope of these variables is the method or constructor in which they are defined. The lifetime is limited to the time for which the method keeps executing. Once the method finishes execution, these variables are destroyed.
public int foo(int argumentVariable)
public class Foo{
public Foo(int constructorVariableArgument)
constructorVariable = constructorVariableArgument
}
Local Variables
A local variable is the one that is declared within a method or a constructor (not in the header). The scope and lifetime are limited to the method itself.
public void foo(){
int methodVariable = 0;
}
Loop Variables
Loop variables are only accessible inside of the loop body
while(condition){
String foo = "Bar";
.....
}
//foo cannot be accessed outside of loop body.
Make it a class variable. This way, when you call the constructor, you will fill the results array and can use it elsewhere in your class. You'll also want this class variable to be private.
public class StudentChart {
private int[] results;
public StudentChart(int[] Results) {
results = Results;
}
}
Related
How is the compiler not complaining when I write the following code?
public class MyClass
{
private int count;
public MyClass(int x){
this.count=x;
}
public void testPrivate(MyClass o){
System.out.println(o.count);
}
}
Even though it is an instance of the same class in which testPrivate is written, shouldn't it give a compilation error at System.out.println(o.count)? After all, I am trying to access a private variable directly.
The code even runs fine.
A private member is accessible from any method within the class in which it is declared, regardless of whether that method accesses its own (this) instance's private member or some other instance's private member.
This is stated in JLS 6.6.1:
...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.
This feature of Java allows you to write methods that accept an instance of the class as an argument (for example - clone(Object other), compareTo(Object other)) without relying on the class having non private getters for all the private properties that need to be accessed.
Private fields are private to the class as a whole, not just to the object.
Other classes do not know that MyClass has a field called count; however, A MyClass object knows that another MyClass object has the count field.
Accessors are not security! They are encapsulation, to keep others from having to know about the code.
Consider if someone wrote a Quantum Bogo Sort, but disappeared once he quashed the last bug -- understanding the code causes one to be either deleted from the universe or to go mad.
Despite this minor drawback, if properly encapsulated, this should become your prefered sorting algorithm, as all fields and methods except Sort should be private.
You don't know how it works, and you don't want to know how it works, but it works and that's enough. If on the other hand, everything is public, and you have to understand how it does what it does to use it correctly -- that's just too much bother, I'll stick with quicksort.
Though it is the instance of the same class in which testPrivate is
written, but shouldn't it through a compiler error at
System.out.println(o.count);
No. It will never throw a compilation error.
This is much similar to what a simple getter and setter does or a copy constructor does. Remember we can access private members using this.
public MyClass {
private String propertyOne;
private String propertyTwo;
// cannot access otherObject private members directly
// so we use getters
// But MyClass private members are accessible using this.
public MyClass(OtherClass otherObject) {
this.propertyOne = otherObject.getPropertyOne();
this.propertyTwo = otherObject.calculatePropertyTwo();
}
public void setPropertyOne(String propertyOne) {
this.propertyOne = propertyOne;
}
public String getPropertyOne() {
return this.propertyOne;
}
}
Your testPrivate method accepts an instance of MyClass. Since testPrivate is a method inside MyClass, it will have access to private properties.
public void testPrivate(MyClass o) {
this.propertyOne = o.propertOne;
}
Methods defined inside the class will always have access to it's private members, through this. and instance variable.
But if you define testPrivate outside of MyClass then, you won't have access to private members. There you will have to use a method or a setter or a getter.
Methods, Variables and Constructors that are declared private can only be accessed within the declared class itself. Check the official documentation
How is the compiler not complaining when I write the following code?
public class MyClass
{
private int count;
public MyClass(int x){
this.count=x;
}
public void testPrivate(MyClass o){
System.out.println(o.count);
}
}
Even though it is an instance of the same class in which testPrivate is written, shouldn't it give a compilation error at System.out.println(o.count)? After all, I am trying to access a private variable directly.
The code even runs fine.
A private member is accessible from any method within the class in which it is declared, regardless of whether that method accesses its own (this) instance's private member or some other instance's private member.
This is stated in JLS 6.6.1:
...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.
This feature of Java allows you to write methods that accept an instance of the class as an argument (for example - clone(Object other), compareTo(Object other)) without relying on the class having non private getters for all the private properties that need to be accessed.
Private fields are private to the class as a whole, not just to the object.
Other classes do not know that MyClass has a field called count; however, A MyClass object knows that another MyClass object has the count field.
Accessors are not security! They are encapsulation, to keep others from having to know about the code.
Consider if someone wrote a Quantum Bogo Sort, but disappeared once he quashed the last bug -- understanding the code causes one to be either deleted from the universe or to go mad.
Despite this minor drawback, if properly encapsulated, this should become your prefered sorting algorithm, as all fields and methods except Sort should be private.
You don't know how it works, and you don't want to know how it works, but it works and that's enough. If on the other hand, everything is public, and you have to understand how it does what it does to use it correctly -- that's just too much bother, I'll stick with quicksort.
Though it is the instance of the same class in which testPrivate is
written, but shouldn't it through a compiler error at
System.out.println(o.count);
No. It will never throw a compilation error.
This is much similar to what a simple getter and setter does or a copy constructor does. Remember we can access private members using this.
public MyClass {
private String propertyOne;
private String propertyTwo;
// cannot access otherObject private members directly
// so we use getters
// But MyClass private members are accessible using this.
public MyClass(OtherClass otherObject) {
this.propertyOne = otherObject.getPropertyOne();
this.propertyTwo = otherObject.calculatePropertyTwo();
}
public void setPropertyOne(String propertyOne) {
this.propertyOne = propertyOne;
}
public String getPropertyOne() {
return this.propertyOne;
}
}
Your testPrivate method accepts an instance of MyClass. Since testPrivate is a method inside MyClass, it will have access to private properties.
public void testPrivate(MyClass o) {
this.propertyOne = o.propertOne;
}
Methods defined inside the class will always have access to it's private members, through this. and instance variable.
But if you define testPrivate outside of MyClass then, you won't have access to private members. There you will have to use a method or a setter or a getter.
Methods, Variables and Constructors that are declared private can only be accessed within the declared class itself. Check the official documentation
Is there any other use of this keyword other than accessing member variable having the same name as local variable
this.x = x
Is there any other situation where it make sense to use this keyword.
One other use of this keyword is in constructor chaining, for example:
class Person {
private String name;
private int age;
public Person() {
//Invoking another constructor
this("John", 35);
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
You can pass the current object as a parameter to another method.
Below points have been taken from Java docs
The most common reason for using the this keyword is because a field is shadowed by a method or constructor parameter.
From within a constructor, you can also use the this keyword to call another constructor in the same class.
this represents the current instance inside the instance.
It is useful for:
identifying instance variables from locals (including parameters)
it can be used by itself to simply refer to member variables and methods, invoke other constructor overloads.
refer to the instance.
Some examples of applicable uses (not exhaustive):
class myClass
{
private int myVar;
public myClass() {
this(42); // invoke parameterized constructor of current instance
}
public myClass(int myVar) {
this.myVar = myVar; // disambiguate
}
public void another() {
this.second(); // used "just because"
}
private void second() {
System.out.println("whatever");
}
}
You can reference a field or call a method of an enclosing class
public class Examples {
public class ExamplesInner {
private int x;
public ExamplesInner() {
x = 3; // refers to ExamplesInner.x
Examples.this.x = 3; // refers to Examples.x
}
}
private int x;
}
For full usage, read the java language specification
The keyword this may be used only in the body of an instance method,
instance initializer, or constructor, or in the initializer of an
instance variable of a class. If it appears anywhere else, a
compile-time error occurs.
When used as a primary expression, the keyword this denotes a value
that is a reference to the object for which the instance method was
invoked (§15.12), or to the object being constructed.
The type of this is the class C within which the keyword this occurs.
At run time, the class of the actual object referred to may be the
class C or any subclass of C.
The keyword this is also used in a special explicit constructor
invocation statement, which can appear at the beginning of a
constructor body (§8.8.7).
this keyword can be used to refer current class instance variable.
this() can be used to invoke current class constructor.
this keyword
can be used to invoke current class method (implicitly)
this can be
passed as an argument in the method call.
this can be passed as
argument in the constructor call.
this keyword can also be used to
return the current class instance.
find examples from this:
http://javarevisited.blogspot.in/2012/01/this-keyword-java-example-tutorial.html
The this operator is used as reference to currently executing object. It is concerned with objects, and hence cannot be and should not be used with static references, where classes are used instead of objects.
The this operator can be used to invoke the constructor like this()
The this operator also avoids naming ambiguities and can be used to pass the current object as reference to functions
this lets you disambiguate between the private member foo and the parameter foo passed into the constructor: EX
class bar
{
private int foo;
public Foo(int foo)
{
this.foo =foo;
}
}
This is the pac.java file
package P1;
public class pac {
int a;
public int b;
private int c;
protected int d;
public pac(){
a=1;
b=2;
c=3;
d=4;
}
public void test(){
System.out.println(a);
System.out.println(b);
System.out.println(c);
System.out.println(d);
}
}
This is other file pack1.java in different package
package P3;
class pac1 extends P1.pac{
public static void main(String args[]) {
pac1 ob=new pac1();
ob.test();
}
}
Question:
How is that possible that from the two files I have shown, the file P3\pac1.java creates an object which access the private variable of the class P1\pac.java?
In Java, a subclass object cannot access private variables (or methods) of any super class.
In your example, pac1 class only access public functionality of class pac, such as the public default constructor & the public method test(). Since the implemnetation of these methods is defined within the super class, both can access its private funvtionality - such as the private int c.
If you override these method in subclass however, the overriding methods implementation won't be able to access class pac private functionality.
HTH.
The method " test() " is inside of the class "pac". Therefore, when you create an instance of pac, the test method belongs to this instance, and can see and use all the variables.
If you had done this, it would have caused an error.
int mainC = ob.c;
the main method (where this is happening) cannot access the variable "c"
What I understand from your unalligned code is that you instantiate a public class and call a public method of it. This is perfectly fine, the test() method has access to variables. You can't access them directly from another method in pac1.
pac1.java only didn't access the private member c of pac.java. It only called the public method test of pac, and that method access the member of the same class.
If I understand you correctly, you are curious how calling ob.test () accesses the private members, despite ob being an object of the derived class. The reason is that whether a method has access is determined at compile time, not run time, and is determined by the location of the method. Your test method is declared in your pac class. So the compiler gives it access to all the private members of the pack class. Now, when it comes to executing the method, it transpires that the type of object your method is executing on is pac1. That does not matter.
This feature of object oriented languages is not a mistake. It makes it possible for the writer of a class to provide limited access to private members, by providing a method that gives only that limited access.
The statement pac1 ob=new pac1(); is creating a new object of Pac1 class and it is possible because it is public.
using ob.test() you are calling a method on the object itself. As private int c is member of the same class in which test() is defined, it can access it.
A private member variable or method is accessible throughout the class in which it is defined.
You can create the object of Pac1 because the class is public.
To clarify your doubt, you cannot access the private member outside the class like this ob.c in the main method.
Consider a very simple example. For a javabean, we make member as private and getter setters as public. We can access them using only getter and setter as they are public.
public class SomeClass{
private int someMember;
public int getSomeMember(){
return this.someMember;
}
}
Now from outside the class,suppose in your main method,
SomeClass someClass = new SomeClass();
someClass.someMember; // This is not possible as we are directly accessing private field
someClass.getSomeMember; // possible because `getSomeMember` is public and it belongs to `SomeClass` so can access private member `someMember`.
`
Is There a Way to Access the Outside?
public class OuterClass {
String data;
public void outerMethod(String data) {
this.data = data;
}
public enum InnerEnum {
OPTION1("someData"),
OPTION2("otherData");
InnerEnum(String data) {
// Does not work:
OuterClass.this.outerMethod(data);
}
}
}
As Eric said, enums are implicitly static. To do what you want, add a method, callOuterMethod(OuterClass oc) that calls oc.outerMethod(data) to do what you want:
public enum InnerEnum {
OPTION1("someData"),
OPTION2("otherData");
final String data;
InnerEnum(String data) {
this.data = data;
}
void callOuterMethod(OuterClass oc) {
oc.outerMethod(data);
}
}
Can't do that. The enum is implicitly static, even though you didn't declare it to be. See similiar question/answer:
"Nested enum types are implicitly static. It is permissable to explicitly declare a nested
enum type to be static."
In Java, are enum types inside a class static?
I believe you're confusing object instances with types. What you have declared is two nested types. That is not the same as two nested object instances.
The keyword this has no meaning when operating with types. It only takes on meaning when dealing with object instances. So, if you're trying to call an instance method of the outer type from the inner type then you need a reference to an instance of the outer type.
However, if you make the method of the outer type static then you can invoke the static method from the nested type without needing a reference to an instance of the outer type. Just keep in mind that if you do that, the method is "the same for all instances" - meaning that it shares any state with all instances of the OuterClass - so it can only access static members of the type.
In the example below, the outerMethod is declared static, and as such it can be called from the nested type without needing a reference to an instance of OuterClass. However, by doing that, it can no longer access the private instance member data (without a reference to an instance of course). You could declare a static member staticData and access that instead, but just keep in mind that that member will be shared by all instances of OuterClass, and by all invokations of outerMethod.
public class OuterClass {
String data; // instance member - can not be accessed from static methods
// without a reference to an instance of OuterClass
static String staticData; // shared by all instances of OuterClass, and subsequently
// by all invocations of outerMethod
// By making this method static you can invoke it from the nested type
// without needing a reference to an instance of OuterClass. However, you can
// no longer use `this` inside the method now because it's a static method of
// the type OuterClass
public static void outerMethod(String data) {
//this.data = data; --- will not work anymore
// could use a static field instead (shared by all instances)
staticData = data;
}
public enum InnerEnum {
OPTION1("someData"),
OPTION2("otherData");
InnerEnum(String data) {
// Calling the static method on the outer type
OuterClass.outerMethod(data);
}
}
}