How to use a Get method in java - java

A ton of questions have been asked on how to create getter and setter methods in java. But i have yet to see one that actually tells me how to use it.
Say i have Private int i = 1; in class A and i want to access it in class B.
I would first create a get method in class A called getIntI(); which would return the value of i.
Then in class B if i wanted to create an if statement that would need the value of i how would I get int i's value. The following is my try and calling the get method which does not work.
if(getIntI == 1)
{System.out.print.ln("int i is one");}
It is probably a really stupid question but i cant find an answer for it elsewhere.

In class A:
public int getIntI(){
return i;
}
Note: Now since your variable is single character named (just I), getter method is named getIntI since the name getI makes lesser sense. But generally, getter methods are something like get+VariableName and do not involve mentioning type. For example if I had a variable called int count, my method would be named getCount instead of getIntCount. Thats the general convention.
Also, naming variables in single char formats (like x, y etc) is discouraged because it may create confusion and management difficulty in complex programs. Though in very small programs they are fine.
Moving back to topic, if you want to access method getIntI() in class B, you will either have to inherit class A or create an object of class A reference to its method.
For class B:
Creating object
A obj = new A();
if(obj.getIntI() == 1)
// Do stuff
Inheriting class A:
public class B extends A{
... // Your stuff
if(getIntI() == 1)
// Do stuff
... // Your stuff
}
Of course there are other ways but these are simpler ones.

if class B extends class A then do only this changes,
if(getIntI() == 1)
If above inheritance was not there then do this,
if(new A().getIntI() == 1)

The problem is that you need to create a object derived from class A before you can access its variables/methods using
A a = new A();
where "a" is the name of the object. Then you can access the getter method by calling a.getIntI. You can also declare the int variable as static so that you wouldn't have to instantiate any objects. An example of class A with the static variable and getter method would be:
public class A {
private static int i = 1;
public static int getIntI() {
return i;
}
}
With this, you can call the getter method with A.getIntI().

First, if you want to access one of A's non-static methods (in this case, getIntI), you need an instance of A, or you can just declare it static.
Secondly, A method call needs a parameter list, even an empty one is needed. getIntI does not need any parameters, so you should add () at the end.
Now, you can get an instance of A somewhere and call it aObj. Andd then you can use it in the if statement:
if (aObj.getIntI == 1)
And remember to add ()!
if (aObj.getIntI() == 1)
Alternatively, you can declare i in A as static. There are two main differences between a static and a non-static variable.
You don't need an instance of the declaring class to access the static variable.
Unlike non-static variables, there is only one static variable. If you have a non-static variable i, you can create lots of instances of A and each instance will have its own i
Now let's see this in action, declare i as static:
public class A {
private static int i = 1;
public static int getIntI () { return i; }
}
Note how both i and getIntI are declared static.
Then you can use in a if statement like this:
if (A.getIntI() == 1)
Note how I use the class name A to access the method, not an instance of A.

Related

What happens to variables/objects in inner classes of function objects?

I have a function multi2 which returns inner class Inner as an Object.
What happens to a - where is it saved and how can I access it?
public class C {
private static Object multi2(final int a) {
class Inner {
public int hashCode() {
return 2*a;
}
}
return new Inner(); // What happens to a?
// Who allocates a?
// Can I Access a?
}
public static void main(String[] args) {
Object o = multi2(6);
System.out.println("o.hashCode() = " + o.hashCode());
o = multi2(4);
System.out.println("o.hashCode() = " + o.hashCode());
}
}
What happens at the implementation level is that a copy of the value of a is saved in a synthetic instance variable declared in the compiled version of the C.Inner class.
The value of a is passed to the compiled Inner constructor via an extra parameter.
The C.Inner.hashCode method uses the value of the synthetic variable. Accessing a in the source code of Inner.hashCode is transformed into accessing the corresponding synthetic variable in the compiled code.
The variable in the outer scope must be final1. The synthetic variable must be final2 in the Inner class. This maintains the illusion that (potentially) multiple instances of the Inner class are seeing the same a variable. (They aren't, but since the variable(s) can't be changed, it is not possible for the code of the inner class to tell the difference.)
If you use javap to look at the bytecodes for the compiled example, you will see the mechanisms used to implement this in the outer and the inner classes.
1 - or effectively final from Java 8 onwards.
2 - If a could be mutated by an Inner method, then two Inner instances with the same outer class need to share a mutable variable whose lifetime is (now) longer than the stackframe for a multi2 call. That entails somehow turning a from stack variable into something that lives on the heap. It would be expensive and complicated.
You have defined the class Inner inside the function so the scope of the class will be
restricted with in the method. And your function is static so it will be live as long as the class definition is loaded. You have override the hashCode function inside the InnerClass so every time you are calling the multi2(param) you are creating the hashCode for the instance of InnerClass and returning the instance of the InnerClass.
So as for you questions, please correct me if i am wrong.
What happens to a ?
a is with in the scope of your static method, so it will be live as long as the class definition is loaded.
Who allocates a?
scope of a is restricted inside the static method and static method does not require instance to access it but as for the static method/variable allocation, i think it depends on JVM.
Can I Access a?
No you cannot access a from outside you static method, it is restricted with in your static method.
Since the "a" is a local parameter, you could use a different approach to read the "a" value:
public class C {
public static Object multi2(final int a) {
return new Inner(a);
}
public static void main(String[] args) {
Object o = multi2(6);
System.out.println("o.hashCode() = " + o.hashCode());
System.out.println("o.getA() = " + ((Inner) o).getA());
o = multi2(4);
System.out.println("o.hashCode() = " + o.hashCode());
System.out.println("o.getA() = " + ((Inner) o).getA());
}
}
class Inner{
public int valueA;
public Inner(int a)
{
valueA = a;
}
public int getA() {
return valueA;
}
public int hashCode() {
return 2*valueA;
}
}
I wanted to know what was actually happening, so I compiled your code and looked at the bytecode output.
Basically what happens is the compiler adds in a constructor to your class 'Inner'. It also adds a single parameter to that constructor which takes 'a'. If your multi2() method was NOT static then there would probably also be a parameter to take 'this' where 'this' is the instance of 'C' that multi2() is executing on. BUT since we're in static context, there is no 'this'.
The compiler adds a private final field to your class 'Inner' and sets that private field using the value passed via the constructor. The compiler also converts
new Inner()
into
new Inner(a)
Hashcode then accesses the private field containing the value for a.
If 'a' was an object instead of a primitive, then it would be the same way, but a reference would be passed through instead of an actual number value.
How do you access this variable? Well you access it with reflections, but there are many problems:
1) You don't know the name of the field made by the compiler, so you can only get the name by looking at the bytecode. Don't trust decompilers as they might change the name. You gotta look at the bytecode yourself to find out.
2) The compiler probably marks the field as final, which means even if you can get reflections to access the field for you, you won't be able to update it.
3) It is entirely up to the compiler to figure out field names. Field names could change between builds depending on the compiler and it's mood.
Inner is a so called local class. a is a parameter passed to the method multi2 and accessable within that scope. Outside of that method, you cannot access a.

No parentheses in java

I am learning Java and I have learned that methods use parentheses for passing parameters. However, I have also noticed that sometimes I see code which to me looks like a method but it does not have parentheses.
MyObject.something()
MyObject.somethingElse
Where somethingElse does not have parentheses. I assume this is similar to how an arrayList has the size method for getting its size:
myList.size()
whereas an array has length to get its size, which does not have parentheses:
myArray.length
Is my assumption correct? If not, what is the difference?
This is probably an elementary question, but because of the amount of words I need to explain this problem, I have had trouble searching for it.
somethingElse is a property (data member), not a method. No code in the class is run when you access that member, unlike with a method where code in the class is run.
Here's an example:
public class Foo {
public int bar;
public Foo() {
this.bar = 42;
}
public int getBlarg() {
// code here runs when you call this method
return 67;
}
}
If you create a Foo object:
Foo f = new Foo();
...you can access the property bar without parens:
System.out.println(f.bar); // "42"
...and you can call the method getBlarg using parens:
System.out.println(f.getBlarg()); // "67"
When you call getBlarg, the code in the getBlarg method runs. This is fundamentally different from accessing the data member foo.
it is a class field which isn't a private field (usually it can be protected,package or public), so you can take it straight from your class. Usually fields are private, so you cannot take it like this outside your class definition.
myList.size() call a method defined in list class (public defined)
myArray.length call a property in array class not method
public class MyClass{
public int length;
public int size(){
....
}
}
MyClass mc =new MyClass();
mc.length;
mc.size();
This is triggering method called something of the instantiated object called someObject.
someObject.something();
This is accessing a property of the object called someObject (property which is public, most probably).
someObject.name

this.method() is referring to?

I have a question regarding this. statement.
Let's say I have this code right here (very stupid and useless but gets the message across):
class Calculate{
int x,y;
final int g = 5;
//Constructor
public Calculate(int a, int b) {
x = a; y = b;
}
public int sumAddG() {
return (x+y+g);
}
//comparing method
public boolean same(Calculate in) {
if(this.sumAddG() == in.sumAddG()) { // <-- This is what I am curious about
return true;
} else {
return false;
}
}
So do I have this code right? When I am using this.SumAddG() - Am I referring to the result of the method SumAddG() using the instance variables of this class instance?
this refers to the actual instance whose same() method has been invoked. Eg. take the following code:
Calculate a = new Calculate(0, 3);
Calculate b = new Calculate(0, 4);
boolean calcFlag = a.same(b);
In this case the this in the method same() will refer to a while in will refer to b.
Update for this line:
if(this.sumAddG() == in.sumAddG()) { // <-- This is what I am curious about
you have a boolean method. In if you're evaluating a boolean expression and you return a boolean true value if the expression itself is true. This can be simplified by simply writing
return this.sumAddG() == in.sumAddG();
This will return directly the evaluation of the two instance's equality. Generally, it is considered good practice in case of boolean methods to evaluate the expression in the return line, while evaluating it in an
if (<*any boolean expression*>) {
return true;
} else {
return false;
}
structure is considered bad practice.
You have multiple issues in the code:
You are using this. in a static method: this. refers to the current instance of your class (the Calculate instance you're in), and static method belongs to the class, not the instance
You are referring to sumAddG() as a property member (in.SumAddG), which is wrong because SumAddG is a method.
In your example, you would use this. if you wish to call the method in your own class instance, but if you wish to call it on another instance in, then you would call it as in.sumAddG().
In static methods, you cannot use this because a static member does not belong to an instance, it belongs to the class, hence there is no recognition of this, as current instance does not exist.
However, if you have a method in the same class and you'd like to call it from a static method, the other method would have to be static as well, and you can call it as: Calculate.MyStaticMethod().
Had your method not been static, then this.sumAddG() == in.sumAddG() would actually compare the return value from calling sumAddG() in your instance, and sumAddG() on in instance.
The current state of your code (your edits are hard to follow) works as you probably expect.
this refers to the instance of the class you are in, so this.sumAddG()'s result uses the above fields current values. in.sumAddG() uses the fields of the instance in, which is specified as a parameter of the method same().
REMOTELY RELATED:
FYI, the use of this here is not needed, as its the default behaviour of the plain call sumAddG(). This means that your if statement could be:
if (sumAddG() == in.sumAddG()) { ... }
The this keyword refers to the current class you are in.
So in that example class you wrote, if you declare an instances variable, Calculate in. Then in the IF statement condition you would refer to it by putting the this keyword in front of it like: this.in
and to refer to the method's parameter by just calling:
in
The this keyword refers to an instance of the class you're using it in.
In the example you've shown this.sumAddG() would be referring to the method of an instance of the class Calculate. Since you're referring to a class instance you cannot use this from a static context.
this always refers to the class instance.
this.method() has nothing to do with the return value. some method have no values to return.
It mean: please compiler call this class instance membered method for
me.

What is the "non-static method" error and how does "this" work?

I have a couple of EXTREMELY basic Java questions that I would like to finally understand, once and for all. I have the following short piece of code:
public class VeryBasicJava{
public static void main(String[] args){
int x = 3;
int y = 4;
swapMe(x, y);
}
private void swapMe(int a, int b){
int a;
int b;
int tmp = a;
this.a = b;
this.b = a;
}
}
When I compile, I get the dreaded "non-static method swapMe(int,int) cannot be referenced from a static context" error. Also, I get "a is already defined in swapMe(int,int)" and "b is already defined in swapMe(int,int)"
What I need to finally get through my thick skull, is the "non-static method" error, how (why) it is caused, and how to avoid it.
Further, I was under the assumption that you could do what I am attempting to do with my 'a' and 'b' variables in the "swapMe" method. I thought I could pass in an 'a' and 'b', but also create new variables 'a' and 'b', and reference them with "this" keyword.
I know this is extremely basic, but these two "issues" are two of the main sticking points I have with Java, and for some reason, cannot seem to properly learn.
Thank you all, for taking the time to read this. Have a great day.
That means that the method swapMe() is an instance method and you need an instance of the VeryBasicJava class to invoke it, like this:
VeryBasicJava instance = new VeryBasicJava();
int x = 3; int y = 4;
instance.swapMe(x, y);
Alternatively, you could declare swapMe() as static, in that way you won't need to create an instance first:
private static void swapMe(int a, int b)
You have just a few minor problems. You mentioned in a comment that you have some experience with C, so I’ll try to draw some basic analogies. A static method (such as main) behaves like an ordinary C function. A non-static method, however, takes a hidden parameter: this, which refers to an object on which that method is to operate. When you write a method such as this:
private void swapMe(int a, int b) {
// ...
It really means something like this:
private void swapMe(VeryBasicJava this, int a, int b){
// ^^^^^^^^^^^^^^^^^^^^
// ...
Because the this parameter is treated specially, there is a special syntax for calling non-static methods on objects:
myInstance.swapMe(someA, someB);
// ^^^^^^^^^^ ^^^^^ ^^^^^
// this a b
And because swapMe is not declared static, it expects to be called like the above.
The fact that main is declared inside the VeryBasicJava class does not mean that you automatically have a VeryBasicJava object. Again, because main is static, it is just like an ordinary C function:
void VeryBasicJava_main(...) {
// ...
In order to create an instance of an object, you use new:
VeryBasicJava vbj = new VeryBasicJava();
This is analogous to malloc in C:
VeryBasicJava *vbj = malloc(sizeof(VeryBasicJava));
VeryBasicJava_construct(vbj);
With an instance, you can invoke a method:
vbj.swapMe(spam, eggs);
Your other issue is twofold: one of scope, and of members. Scope, as you may know, refers to where a variable exists. Take this function:
1: private void swapMe(int a, int b) {
2: int a;
3: int b;
4: int tmp = a;
5: this.a = b;
6: this.b = a;
7: }
When this method is called, the following things happen:
a and b are created, given the values specified in the call to swapMe.
A new a is created, local to swapMe, with the default value 0. This a hides the parameter a, and there is no way to differentiate them.
A new b is created, also strictly local. It too has the default 0 value, and hides the parameter b.
tmp is created, and its value is set to that of the newly declared a, so it too is 0.
[see below]
[see below]
The locals a and b cease to exist, as do the parameters a and b.
In lines 5 and 6, you attempt to use the syntax this.a to refer to the local a rather than the parameter. Though this syntax exists in Java, it does not do what you mean. Parameters are treated just the same as local variables, so rather than differentiating between those two categories, this.a differentiates between locals and members. Now, what are members? Well, say your class declaration contains variable declarations:
class VeryBasicJava {
private int a;
private int b;
// ...
}
That’s just like member declarations in a C struct:
struct VeryBasicJava {
int a;
int b;
};
What this means is that when you create an instance of VeryBasicJava:
VeryBasicJava vbj = new VeryBasicJava();
That instance has its own variables a and b, which can be used in any non-static method:
public void print() {
System.out.println("a is " + a);
System.out.println("b is " + b);
}
If you have a local variable with the same name as a member, then you must use this to explicitly state that you want to refer to the member. This complete program illustrates how to declare, use, and differentiate between members and locals.
class VeryBasicJava {
private int a;
private int b;
private int c;
public static void main(String[] args) {
VeryBasicJava vbj = new VeryBasicJava();
vbj.a = 3;
vbj.b = 4;
vbj.c = 5;
vbj.print(1);
}
public void print(int a) {
int b = 2;
System.out.println("a is " + a);
System.out.println("b is " + b);
System.out.println("c is " + c);
System.out.println("this.a is " + this.a);
System.out.println("this.b is " + this.b);
System.out.println("this.c is " + this.c);
}
}
It will produce this output:
a is 1
b is 2
c is 5
this.a is 3
this.b is 4
this.c is 5
I hope these examples and explanations are helpful.
Your problems stem from not understanding how the object-orientated paradigm works.
The idea is that you define a class, which is a "type of thing". From that class, you create instances, which are effectively examples of that type of thing.
For example, when you create a class "Wallet", that defines how your
system will treat wallets (i.e. what they can do, and what you can do
with them). You can now create multiple different instances of
wallets, that store different values, but still work the same way.
(e.g. "myWallet" and "yourWallet" are both Wallets, so you can take
money out and put money in etc, but if I check the money in
yourWallet, I get a value of 50, whereas if I check the value in
myWallet, I get a value of 20)
Now, "static" methods belong to the class. This means that they can't access members variables specific to the class. For example, if I'm keeping track of every wallet in my system, that value doesn't belong to any particular wallet in the class, but it's still involved with that class, so we make it static.
To use my example, if you have two objects of type "Wallet", and one
has its "cash" value set to 30, and the other has its cash value set
to "25", a static function can't access both values, so it can't
access either. You have to give it a particular wallet to access.
The advantage of this method over C's approach is that it ties related functionality together. For example, if you see a C array of ints, you don't really know what they are intended to represent and may do something unexpected with them. But if I give you a Java array of Wallets, you also get the methods that influence how you interact with them. (This is a really stripped down explanation of encapsulation)
One of the principle issues with Java is that it ties everything to a class. This causes a problem for the main method, which has to start the program, because it has no instances yet, but must still be part of the class. Therefore the main method must always be static. This tends to confuse new programmers, as invariably the first thing you do within the main method is create an instance of the class it's "inside".
In your example, you've got no "specific" data. Everything's inside the methods, which means you're effectively trying to write procedural code in Java. You can do this (just declare everything static), but the language will fight you, and you'll write very bad code.
When I was originally starting out with Java, I effectively treated the main() method of a class as if it wasn't part of the class. Conceptually, it helped, because you stop thinking of the non-static stuff as something that's already there (which is your main issue). But my recommendation to you is try reading through this. But there are some very good transition courses out there for learning object-orientated programming, and you may want to invest in them.
Classes are a template for OBJECTS. An instance of a class (i.e. and object) has its own version of variables and methods that are non-static.
static methods and fields are not tied to any specific instance of a class.
So it makes no sense to invoke a class instance method from a static method, without the instance on which you want to invoke the method. In your example, this is a reference to an instance, but you have no instance....
For your second question, when you create a function, it creates its own little stack for all of its variables. Its arguments are included in that stack - so, your stack looks like this:
int a; //this is the first argument
int b; //this is the second argument
int a; //this is the first line of your function
int b; //this is the second line of your function
That's why you're getting an issue - the a and b you declare after your arguments are conflicting with your arguments, not "this.a" and "this.b".
Your first question has already been answered.
As the fix's been provided, I would like to add:
static methods can only call other static methods and access only static variables directly (in java).
To call non-static methods, you have create an instance of that class and call the methods then.
swapMe needs an instance of VeryBasicJava to invoke it. Static does not.
From outside that object, you could call: VeryBasicJava.main(args).
From outside the object, you would need to do (new VeryBasicJava()).swapMe(a,b) to invoke that method.
The reason you are getting errors inside of swapMe is because you are defining those variables twice. The signature line declared them in that namespace for you. In that method, you already have an int a. Then on the first line, you declare int a again.
What you want to do in your swap is something like this:
private void swapMe(int a, int b){
int tmp = a;
a = b;
b = tmp;
}
Of course the variables a and b only exist in that method so as soon as the method ends your work is lost. If you wanted to keep it, make the variables class variables and provide getters and setters for them.

Accesing a method from another class file?

I need to acces a variable (an int) from another class file. How would I do this? It's a public int, I need to get the int value and put it into a file.
If you have an instance:
AnotherClass another = new AnotherClass();
Then if the field (instance variable) is public:
another.someField;
or if you have a getter method
another.getSomeField();
If none of these is true - add a getter method (this is the preferred way to access instance variables).
If you can't change the class - as a last resort you can use reflection.
Example:
MyClass myclass = new MyClass();
System.out.print(myclass.myint)
Best practice code states that if the variable is not a Static Final, then you should create getters & setters inside the class:
public class Main{
int variableName;
public int getVariableName(){
return this.variableName;
}
public setVariableName(int variableName){
this.variableName = variableName;
}
}
If you want to acess it from another class file then you have to instantiate an Object and then access it using the public method:
Main m = new Main();
int a = m.getVariableName();
Hope it helps.
If you have an instance of that other class, you access it as {instance}.varable.
That varaiable need to either be public, or it needs to be in the same package and not private, or it must be a protected variable in a superclass.
If the variable is static, then you don't need an instance of that class, you would access it like {ClassName}.variable.
Far and away the best thing to do here would be to make the int you need to access a Property of the other class and then access it with a 'getter' method.
Basically, in the other class, do this:
public int Number
{
get
{
return number;
}
set
{
number = value;
}
}
private int number;
Doing this allows you to easily set that in to something else if you need to or to get it's current value. To do this, create an instance of the "AnotherClass" as Bozho already explained.

Categories

Resources