I was supposed to write this code so that ArrIg is a static nested class of Pair. However, I declared them as independent classes, but the code still ran as expected. I understand why it still ran.
I understand that static prevents the ArrIg object from being called once Pair is called(assuming ArrIg was a nested class of Pair). Further, this violated the syntax for static nested class, but it still worked. What are some of the dangers I have exposed this code to ?
public class ClassPair {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] Ig= {1,2,3,4};
Pair pair= ArrIg.minmax(Ig);
System.out.print("min :"+pair.getFirst()+" | max :"+pair.getSecond());
}
}
class Pair {
public Pair(int a, int b){
first=a;
second=b;
}
public int getFirst(){
return first;
}
public int getSecond(){
return second;
}
private int first, second=0;
}
class ArrIg{
public static Pair minmax(int [] a){
int min= a[0];//1
int max=a[0];//1
for(int i=0; i<a.length;i++){
if (min>a[i]) min =a[i];//1
if (max<a[i]) max=a[i];//2,3,4
}
return new Pair(min ,max);
}
}
Access modifiers and nested classes are not a security mechanism. Indeed, it is pretty much trivial to circumvent them via reflection. (The only scenario where it might matter is if you are attempting to implement a system with a security sandbox.
The real purpose for access modifiers and nested classes is to provide encapsulation. It is about is about design leakage (unwanted dependencies) rather than information leakage and more general security concerns.
In this particular example, the (hypothethical) danger is that Pair could be instantiated and used outside of the ClassPair encapsulation. That could (hypothetically) be harmful, but for something like the Pair class allowing this could be a good thing.
I would also add that you need to use the terminology properly if you want people to understand what you are saying. For instance "calling" an object is not meaningful. You call methods ... not objects.
Related
For some background, I'm currently on chapter 8 in my book, we finished talking about arraylists, arrays, if statements, loops etc. Now this part of the book talks about call by reference,value and some other pretty neat things that seem odd to me at first.I've read What situation to use static and some other SO questions, and learned quite a bit as well.
Consider the following example my book gave (among many examples)
There is another reason why static methods are sometimes necessary. If
a method manipulates a class that you do not own, you cannot add it to
that class. Consider a method that computes the area of a rectangle.
The Rectangle class in the standard library has no such feature, and
we cannot modify that class. A static method solves this problem:
public class Geometry
{
public static double area(Rectangle rect)
{
return rect.getWidth() * rect.getHeight();
}
// More geometry methods can be added here.
}
Now we can tell you why the main method is static. When the program
starts, there aren’t any objects. Therefore, the first method in the
program must be a static method.
Ok, thats pretty cool, up until now I've just been really blindly putting public in front of all my methods, so this is great to know. But the review small problem on the next page caught my attention
The following method computes the average of an array list of numbers:
public static double average(ArrayList<Double> values)
Why must it be a static method?
Here I was like wait a sec. I'm pretty sure I did this without using static before. So I tried doing this again and pretty easily came up with the following
import java.util.ArrayList;
class ArrList
{
private double sum;
public ArrList()
{
sum = 0;
}
public double average(ArrayList <Double> values)
{
for(int i = 0; i < values.size() ; i++)
{
sum+=values.get(i);
}
return sum / values.size();
}
}
public class Average
{
public static void main(String [] args)
{
ArrList arrListObj = new ArrList();
ArrayList<Double> testArrList = new ArrayList<Double>();
testArrList.add(10.0);
testArrList.add(50.0);
testArrList.add(20.0);
testArrList.add(20.0);
System.out.println(arrListObj.average(testArrList));
}
}
TLDR
Why does my book say that public static double average(ArrayList<Double> values) needs to be static?
ATTEMPT AT USING STATIC
public class Average
{
public static void main(String [] args)
{
ArrayList<Double> testArrList = new ArrayList<Double>();
ArrayList<Double> testArrListTwo = new ArrayList<Double>();
testArrList.add(10.0);
testArrList.add(50.0);
testArrList.add(20.0);
testArrList.add(20.0);
testArrListTwo.add(20.0);
testArrListTwo.add(20.0);
testArrListTwo.add(20.0);
System.out.println(ArrList.average(testArrList));
System.out.println(ArrList.average(testArrListTwo)); // we don't get 20, we get 53.3333!
}
}
It doesn't.
The only method which needs to be static is the initial main() method. Anything and everything else is up to you as the programmer to decide what makes sense in your design.
static has nothing to do with public accessors (as you allude to), and it has nothing to do with the technical operation being performed. It has everything to do with the semantics of the operation and the class which holds it.
An instance (non-static) method exists on a particular instance of a class. Semantically it should perform operations related to that specific instance. A static method exists on a class in general and is more conceptual. It doesn't do anything to a particular instance (unless it's provided an instance of something as a method argument of course).
So you really just need to ask yourself about the semantics of the operation. Should you need new instance of an object to perform an operation? Or should the operation be available without an instance? That depends on the operation, on what the objects represent, etc.
If it is not static, then any other class that wants to use this method must first create an instance of this object.
From some other class:
Average.average(new ArrayList<Double>()); // legal only if static
new Average().average(new ArrayList<Double>()); // necessary if not static
// and only makes sense if Average can be instantiated in the first place
It's legal to make it an instance (i.e. not static) variable, but the method is actually harder to understand. If it is static then whoever reads the code knows it does not use any member variables of the class.
// In the class body
int x = 0; // member variable
public static double average() {
x = x + 1; // illegal
}
The less something can do, the easier to understand what it does do.
Static methods like the area, average are usually utility functions. You don't need any object to use an utility function. For example consider Math.pow you don't need to instantiate any object to use the power function, just use Math.pow(10.0, 2.0) to get (10.0)^2
In short :
Static method means class method, that is no instance of that object is needed to invoke.
whereas your average method is an instance method, you need an object to invoke that method.
https://stackoverflow.com/a/572550/1165790
I want to use this feature in Java because the function that I'm designing is called rarely (but when it is called, it starts a recursive chain) and, therefore, I do not want to make the variable an instance field to waste memory each time the class is instantiated.
I also do not want to create an additional parameter, as I do not want to burden external calls to the function with implementation details.
I tried the static keyword, but Java says it's an illegal modifier. Is there a direct alternative? If not, what workaround is recommended?
I want it to have function scope, not class scope.
I want it to have function scope, not class scope.
Then you are out of luck. Java provides static (class scoped), instance and local variables. There is no Java equivalent to C's function-scoped static variables.
If the variable really needs to be static, then your only choice is to make it class scoped. That's all you've got.
On the other hand, if this is a working variable used in some recursive method call, then making it static is going to mean that your algorithm is not reentrant. For instance, if you try to run it on multiple threads it will fall apart because the threads will all try to use the same static ... and interfere with each other. In my opinion, the correct solution would be either to pass this state using a method parameter. (You could also use a so-called "thread local" variable, but they have some significant down-sides ... if you are worrying about overheads that are of the order of 200 bytes of storage!)
How are you going to keep a value between calls without "wasting memory"? And the memory consumed would be negligible.
If you need to store state, store state: Just use a static field.
Caution is advised when using static variables in multi-threaded applications: Make sure that you synchronise access to the static field, to cater for the method being called simultaneously from different threads. The simplest way is to add the synchronized keyword to a static method and have that method as the only code that uses the field. Given the method would be called infrequently, this approach would be perfectly acceptable.
Static variables are class level variables. If you define it outside of the method, it will behave exactly as you want it to.
See the documentation:
Understanding instance and Class Members
The code from that answer in Java...
public class MyClass {
static int sa = 10;
public static void foo() {
int a = 10;
a += 5;
sa += 5;
System.out.println("a = " + a + " sa = " + sa);
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
foo();
}
}
}
Output:
$ java MyClass
a = 15 sa = 15
a = 15 sa = 20
a = 15 sa = 25
a = 15 sa = 30
a = 15 sa = 35
a = 15 sa = 40
a = 15 sa = 45
a = 15 sa = 50
a = 15 sa = 55
a = 15 sa = 60
sa Only exists once in memory, all the instances of the class have access to it.
Probably you got your problem solved, but here is a little more details on static in Java. There can be static class, function or variable.
class myLoader{
static int x;
void foo(){
// do stuff
}
}
versus
class myLoader{
static void foo(){
int x;
// do stuff
}
}
In the first case, it is acting as a class variable. You do not have to "waste memory" this way. You can access it through myLoader.x
However, in the second case, the method itself is static and hence this itself belongs to the class. One cannot use any non-static members within this method.
Singleton design pattern would use a static keyword for instantiating the class only once.
In case you are using multi-threaded programming, be sure to not generate a race condition if your static variable is being accessed concurrently.
I agree with Bohemian it is unlikely memory will be an issue. Also, duplicate question: How do I create a static local variable in Java?
In response to your concern about adding an additional parameter to the method and exposing implementation details, would like to add that there is a way to achieve this without exposing the additional parameter. Add a separate private function, and have the public function encapsulate the recursive signature. I've seen this several times in functional languages, but it's certainly an option in Java as well.
You can do:
public int getResult(int parameter){
return recursiveImplementation(parameter, <initialState>)
}
private int recursiveImplementation(int parameter, State state){
//implement recursive logic
}
Though that probably won't deal with your concern about memory, since I don't think the java compiler considers tail-recursive optimizations.
The variables set up on the stack in the recursive call will be function (frame) local:
public class foo {
public void visiblefunc(int a, String b) {
set up other things;
return internalFunc(a, b, other things you don't want to expose);
}
private void internalFunc(int a, String b, other things you don't want to expose) {
int x; // a different instance in each call to internalFunc()
String bar; // a different instance in each call to internalFunc()
if(condition) {
internalFunc(a, b, other things);
}
}
}
Sometimes state can be preserved by simply passing it around. If required only internally for recursions, delegate to a private method that has the additional state parameter:
public void f() { // public API is clean
fIntern(0); // delegate to private method
}
private void fIntern(int state) {
...
// here, you can preserve state between
// recursive calls by passing it as argument
fIntern(state);
...
}
How about a small function-like class?
static final class FunctionClass {
private int state1; // whichever state(s) you want.
public void call() {
// do_works...
// modify state
}
public int getState1() {
return state1;
}
}
// usage:
FunctionClass functionObject = new FunctionClass();
functionObject.call(); // call1
int state1AfterCall1 = functionObject.getState1();
functionObject.call(); // call2
int state1AfterCall2 = functionObject.getState1();
I have a class with several methods. Now I would like to define a helper method that should be only visible to method A, like good old "sub-functions" .
public class MyClass {
public methodA() {
int visibleVariable=10;
int result;
//here somehow declare the helperMethod which can access the visibleVariable and just
//adds the passed in parameter
result = helperMethod(1);
result = helperMethod(2);
}
}
The helperMethod is only used by MethodA and should access MethodA's declared variables - avoiding passing in explicitly many parameters which are already declared within methodA.
Is that possible?
EDIT:
The helper mehod is just used to avoid repeating some 20 lines of code which differ in only 1 place. And this 1 place could easily be parameterized while all the other variables in methodA remain unchanged in these 2 cases
Well you could declare a local class and put the method in there:
public class Test {
public static void main(String[] args) {
final int x = 10;
class Local {
int addToX(int value) {
return x + value;
}
}
Local local = new Local();
int result1 = local.addToX(1);
int result2 = local.addToX(2);
System.out.println(result1);
System.out.println(result2);
}
}
But that would be a very unusual code. Usually this suggests that you need to take a step back and look at your design again. Do you actually have a different type that you should be creating?
(If another type (or interface) already provided the right signature, you could use an anonymous inner class instead. That wouldn't be much better...)
Given the variables you declare at the top of your method can be marked as final (meaning they don't change after being initialized) You can define your helper method inside a helper class like below. All the variables at the top could be passed via the constructor.
public class HelperClass() {
private final int value1;
private final int value2;
public HelperClass(int value1, int value2) {
this.value1 = value1;
this.value2 = value2;
}
public int helperMethod(int valuex) {
int result = -1;
// do calculation
return result;
}
}
you can create an instance of HelperClass and use it inside the method
It is not possible. It is also not good design. Violating the rules of variable scope is a sure-fire way to make your code buggy, unreadable and unreliable. If you really have so many related variables, consider putting them into their own class and giving a method to that class.
If what you mean is more akin to a lambda expression, then no, this is not possible in Java at this time (but hopefully in Java 8).
No, it is not possible.
I would advise you create a private method in your class that does the work. As you are author of the code, you are in control of which other methods access the private method. Moreover, private methods will not be accessible from the outside.
In my experience, methods should not declare a load of variables. If they do, there is a good chance that your design is flawed. Think about constants and if you couldn't declare some of those as private final variables in your class. Alternatively, thinking OO, you could be missing an object to carry those variables and offer you some functionality related to the processing of those variables.
methodA() is not a method, it's missing a return type.
You can't access variables declared in a method from another method directly.
You either has to pass them as arguments or declare methodA in its own class together with the helpermethods.
This is probably the best way to do it:
public class MyClass {
public void methodA() {
int visibleVariable=10;
int result;
result = helperMethod(1, visibleVariable);
result = helperMethod(2, visibleVariable);
}
public int helperMethod(int index, int visibleVariable) {
// do something with visibleVariable
return 0;
}
}
The following code works & runs perfectly.
public class Complex {
private int real, imag;
Complex(int r, int i) {
real = r;
imag = i;
}
public static Complex add(Complex c1, Complex c2) {
return new Complex(c1.real + c2.real, c1.imag + c2.imag);
}
public String toString() {
return real + "+i" + imag;
}
public static void main(String[] args) {
Integer.parseInt("5");
System.out.println(Complex.add(new Complex(2, 3), new Complex(3, 4)));
}
}
Now according to Object oriented design model, private instance members shouldn't be accessed through a object reference (which has been done here by c1.real ).
So, in that sense,there should be compiler error. But it doesn't object.
Now according to my understanding it's allowed because
c1.real code is written in the body of the private class Complex class itself.
Developer of Complex class should have access to all instance members [be it private,protected whatever] when accessing through an object reference, since Developer knows very well what he's doing unlike any third party. That's why object oriented model model isn't followed here.
Can anyone suggest a better explanation about why c1.real code is allowed here?
private means it cannot be access from another outer class. It is class based, not object based security. Note: classes in the same outer class can access private member of any other class in that file.
http://vanillajava.blogspot.co.uk/2012/02/outer-class-local-access.html
The short answer is that because that's the way Java defined the private access modifier.
The longer answer is that they probably assumed that strict encapsulation only makes sense above source file level, so even an inner class can access private members of its outer class (and vice versa): it simply makes no sense to hide members within the same source file. If you've got access to the source file of a class, you can easily modify any access modifiers anyway.
(Although the inner-outer class thing is achieved via synthetic accessors, but they're almost completely transparent.)
what about using "this" with methods in Java? Is it optional or there are situations when one needs to use it obligatory?
The only situation I have encountered is when in the class you invoke a method within a method. But it is optional. Here is a silly example just to show what I mean:
public class Test {
String s;
private String hey() {
return s;
}
public String getS(){
String sm = this.hey();
// here I could just write hey(); without this
return sm;
}
}
Three obvious situations where you need it:
Calling another constructor in the same class as the first part of your constructor
Differentiating between a local variable and an instance variable (whether in the constructor or any other method)
Passing a reference to the current object to another method
Here's an example of all three:
public class Test
{
int x;
public Test(int x)
{
this.x = x;
}
public Test()
{
this(10);
}
public void foo()
{
Helper.doSomethingWith(this);
}
public void setX(int x)
{
this.x = x;
}
}
I believe there are also some weird situations using inner classes where you need super.this.x but they should be avoided as hugely obscure, IMO :)
EDIT: I can't think of any examples why you'd want it for a straight this.foo() method call.
EDIT: saua contributed this on the matter of obscure inner class examples:
I think the obscure case is: OuterClass.this.foo() when accessing foo() of the outer
class from the code in an Inner class that has a foo() method as well.
I use "this" to clarify code, often as a hint that I'm calling an instance method rather than accessing a class-level method or a field.
But no. Unless disambiguation is required due to scope naming collision, you don't actually need "this."
For most general programing, the this keyword is optional and generally used to avoid confusion. However, there are a few places where it is needed.
class Foo {
int val;
public Foo(int val) {
this(val, 0); //this MUST be here to refer to another constructor
}
public Foo(int val, int another) {
val = val; //this will work, but it generally not recommended.
this.val = val; //both are the same, but this is more useful.
method1(); //in a Foo instance, it will refer to this.method1()
this.method1(); //but in a Foo2 instance, you must use this to do the same
}
public void method1() {}
}
class Foo2 extends Foo {
public Foo2(int val) {
this(val); //this will refer to the other Foo2 constructor
}
public Foo2(int val, int another) {
super(val, another);
super.method1(); //this will refer to Foo.method1()
}
#Override
public void method1() {}//overridden method
}
These are not all the cases, but some of the more general ones. I hope this helps you better understand the this and super keywords and how/when to use them.
The only reason to prepend this in front of a method invocation is to indicate that you're calling a non-static method. I can't think of any other valid reason to do this (correct me I'm wrong). I don't recommend this convention as it doesn't add much value. If not applied consistently then it could be misleading (as a this-less method invocation could still be a non-static method). How often does one care if the method being invoked is static or not? Furthermore, most IDEs will highlight static methods differently.
I have heard of conventions where this indicates calling the subclass's method while an absence of this is calling the super class's method. But this is just silly as the convention could be the other way around.
Edit: As mmyers points out (see comment), this works with static methods. With that, I see absolutely no reason to prepend with this as it doesn't make any difference.
The only time it is really required is when you have a parameter to a method with the same name as a member variable. Personally, I try to always use it to make the scope of the variable/method explicit. For example you could have a static method or an instance method. When reading the code it can be helpful to know which is which.
Not an answer (so feel free to vote it down), but I couldn't fit this into a comment where someone was asking.
A lot of people use "this.x" to visually differentiate instance variables from local variables and parameters.
So they would do this:
private int sum;
public int storeSquare (int b) {
int c=b*b;
this.sum+=c; // Makes sum "pop" I guess
return c;
}
Personally I think it's a bad habit: any usable editor will put instance and local variables in a different color for you reliably--it doesn't require any human-fallible patterns.
Doing it with "this." is only 50% safe. Sure the compiler will catch it if you try to put this.x when x is a local variable, but there is nothing that is going to stop you from "Forgetting" to tag an instance variable with this., and if you forget to tag just one (or if someone else works on your code) and you are relying on the pattern, then the pattern may be more damaging than good
Personally I'm fairly sure the pattern stems from programmers (rightful) discomfort with the fact that in this case:
public void setMe(int me) {
this.me=me;
}
the fact that you need "this." in front of the me is determined by the name of the parameter--I agree it just feels sloppy. You want to be consistent--if you need this. in front of the me there, why not always use it?
Although I understand the discomfort, typing this. every single place that an instance variable is used is just pedantic, pointless, ugly and unreliable. If it really bothers you and you absolutely need to use a pattern to solve it, try the habit of putting "p" in front of your parameters. As a side effect, it should even make it more constant because the parameter case will now match the method case..
public void setMe( int pMe)
http://java.sun.com/j2se/1.5.0/docs/api/java/lang/StringBuilder.html
You absolutely need this if your method needs to return the object's instance.
public class StringBuildable {
public StringBuildable append(String text) {
// Code to insert the string -- previously this.internalAppend(text);
return this;
}
}
This allows you to chain methods together in the following fashion:
String string = new StringBuildable()
.append("hello")
.append(' ')
.append.("World")
.toString()
;