public static int f(String input) {
public static Stack<Character> stack = new Stack<Character>();
int n = 0;
for (int i = 0; i < input.length(); i++) {
if (input.charAt(i) == 'd')
stack.push('d');
else if (input.charAt(i) == 'b') {
if (!stack.empty() && stack.pop() == 'd') n++;
}
}
return n;
}
i just want to know the significance of static keyword in object creation...just pasted the whole code here
What everyone else has said so far is all accurate, but I'll elaborate a bit on your question on what "the significance of static keyword in object creation" is.
Static variables last for the lifetime of the class (so essentially from the start till the end of your program). But in your code, you declare your stack variable inside of a method, so that variable is created and destroyed each time that method is run. Therefore it doesn't actually make any sense to be given the keyword static. These variables are meant to be shared among every instance of the class you create. So you should only create that static variable once when your program is run.
(There are ton of resources elsewhere explaining when/where to use static)
Here are a couple I found useful when learning:
stackoverflow link to a similar, but more general discussion on the static keyword
A longer but good beginner introduction to all you need to know about the static keyword
As #azurefrog says, that won't work - I'm guessing you've copied and pasted the line
public static Stack<Character> stack = new Stack<Character>();
from the top of your class for illustrative purposes? If so, you've broken your example in doing so.
Assuming I'm correct and that declaration is from within your class, rather than within that static method, then the answer to your question would be that there will be only a single instance of the stack variable, regardless of the number of instances which you create of the class in which it resides: i.e. all instances which you create of your class will see/contain the same instance of stack, and anywhere it is addressed from outside (valid, given that it's public), should be referring to it as ClassName.stack, not instanceName.stack
Related
I'm studying computer engineering, my 2nd semester just began. I've been making Android applications for a few while.
My programming lecturer (teaches C++ (Object Oriented)) said we can't initialize variables in a class unless we use a constructor since there's no memory dedicated to those data members before making an object of that class.
He said this is incorrect:
class example
{
int a = 0;
};
But my experience says something else:
I've made a class in my Android project that keeps my Constants. I don't make any objects of that class. I've initialized variables and never used a constructor. But it works fine:
public class Constants {
public static final int a = 1;
}
I want to know how am I initializing variables when there's no memory dedicated to that variable and how it works.
What part of my story is wrong? I want to know how my code works when there's no memory dedicated to my variables (Constants)?
The Truth
class A {
int a = 0;
};
In-class initializers became legal in C++11; so the only conclusion to draw from what you have said is that your teacher is living in the past.
However, if he is teaching C++03 and not a later revision of the language, he's correct about it being ill-formed.
It is important to note that what he said regarding (non-static) data-members and their lack of storage until an object of such class has actually been created still applies.
An in-class initializer will initialize the data-member during construction, as long as the data-member isn't initialized in the used constructor's mem-initializer (then the latter takes precedence).
struct A {
A () = default;
A (int x) : m (x) { }
int m = 0; // ^ mem-initializer
};
A x; // `x.m` is initialized to `0`
A y (123); // `y.m` is initialized to `123`
Further Reading
cppreference.com - Non-static data members : Member Initialization
He said this is incorrect:
class example
{
int a = 0;
}
Well, yes, it's incorrect, there needs to be a semicolon at the end, after the }.
With that semicolon, this is legal C++11; the = 0 is a non-static data member initializer (NSDMI for short). It's syntatic sugar for performing the equivalent initialization in the constructor.
public class Constants {
public static final int a = 1;
}
static things are per-class, and exists even if no objects of that class is ever created. Non-static things are per-object.
I need to create a myStack class and then use it to test for Palindromes... I chose to create an ArrayList based implementation of the stack.
import java.util.ArrayList;
public class myStack<AnyType>{
private ArrayList<AnyType> arr;
public myStack(ArrayList<AnyType> a){
arr = a;
}
public void push(AnyType element) {
arr.add(element);
}
public AnyType pop() {
if(arr.size() == 0)
{
System.out.println("Stack Underflow");
return null;
}
else
{
AnyType element = arr.get(arr.size() -1);
arr.remove(element);
return element;
}
}
public AnyType top() {
if(arr.size() == 0)
{
System.out.println("Stack Underflow");
return null;
}
else
return(arr.get(arr.size() -1));
}
}
Then I use it in a class called Palindrome (not complete yet)
However, when I compile, it tells me
"Note: Palindrome.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details."
When I comment out the line myStack m = new myStack(test);
It compiles, so I know this is the problem... Why would the myStack class be the problem? Is it something to do with the "AnyType" I used in the stack class?
Your class myStack. is generic with the template type <AnyType> and is currently using a Raw Type (hence the warning). Please follow Java naming conventions, and rename it MyStack. Then, use it with a type (and in Java 7 and up the diamond operator <>) -
// myStack m = new myStack(test);
myStack<Character> m = new myStack<>(); // <-- Please use MyStack.
if you intend to use MyStack class for any of the type, you can use the wildcard "?".
So your MyStack will be unbounded wildcard type generic class, and therefore hold anything.
Ill add a little perspective.. not answering the question directly..
What does stack have to do with palindrome?
Generics is slightly-advanced/optional concept. There are more important things to learn first. So, fix it if you want.. but you can also ignore the warning.
I would prefer to split the program into 3 aspects - (a) method to check if a single string is palindrome (b) method to read lines in a file (c) method to check if a string contains only digits and numbers
Write separate methods to achieve each of them and get the best quality of code, for example by referring stackoverflow for each
Wire them up together to get the final program working
IMHO... Java is vast and you need to consciously postpone learning stuff like Generics.
Focus on these:
Object oriented design - You could write a StringUtil and add a
static method like checkPalindrome
Variable and class naming convention (Java developers follow conventions almost to last letter)
I will suggest a structure for your program:
Your main class should be named as FilePalindromeChecker
Create a StringUtil class with a static method to check for palindrome:
public static boolean checkPalindrome
Have another static method in StringUtil to check for alphanumeric: public
static boolean checkPalindrome
Happy coding!
Following code is going in else statement. I am not able to find out where i made mistake.
*A want to execute in below comments.
*B is executing in below comments.
package com.java;
import java.util.Scanner;
public class Solution
{
static int n;
static String w[];
public static void main(String[] args)
{
System.out.println("enter no of string between 1 to 50");
Scanner scanner = new Scanner(System.in);
//* A
if ((1<n) && (n<=50))
{
n = scanner.nextInt();
System.out.println("enter " +n+ "strings between 1 to 2000 length");
for (int i=0; i<n; i++)
{
w[i]= scanner.next();
if ((1<w[i].length()) && (w[i].length()<2000))
{
System.out.println("ok");
}
}
System.out.println(w);
}
// *B
else
{
System.out.println("coming due to static");
}
}
}
static means that it is a class variable, that is, it does not belong to an instance of the class. And opposite, a non static variable belongs to an instance of the class. You're referencing the variable n from a static method, and hence, it will not work unless the variable also is declared static.
(and obviously, the if itself won't work because of what the reply from #MarounMaroun mention)
You didn't initialize n, so you're not satisfying the if condition, since uninitialized static int variables are 0 by default.
So:
if ((1<n) && (n<=50)) is not evaluated to true, so else will be executed.
Note that you can't access static variable from non-static method (See #NilsH answer). And that's make a lot of sense..
First, when working with static methods, you must reference static variables. If you try to reference a non-static variable that belongs to a class, the compiler will complain because that is wrong. Static variables do not belong to a class per se.
Second, I think you have a typo or forgot some code. n is never set - ever. Therefore, since in the static context it will be zero initialized and hit the else. I think you meant for n to actually be set before the if statement either via user-input or some other means. If you leave everything static and actually provide a value for n, then your code should work.
For instance, you probably need to make this assignment:
n = scanner.nextInt();
before the if-statement.
there is another problem with your code in reading the next number you want to read, but I will leave that for you to solve.
Have you tried making static int n and static String w[] public?
IE:
public static int n ;
public static String w[] ;
what you probably want is moving all that code to a non-static method. and then in your main method just do something like this
Solution s = new Solution();
s.myNonStaticMethod();
Below you can see a static variable counter in a Java class.
The question is when will this variable reset? For example, when I restart the program, computer. What are the other possible scenarios it can reset?
Another question is: what could be the reasons for this variable to increase by less than the number of times the function do() is executed? For example, could it be something with starting multiple processes of the class java Whatever? Or could it be something with multiple threads/servers, etc?
class Whatever {
static int counter = 0;
function do() {
counter++;
//...
}
}
Additional question: If multiple threads execute function do(), how will the counter variable behave? It will be less than the number of times function do() was executed?
A static variable will be re-initialized when you restart the application.
According to the JLS:
If a field is declared static, there exists exactly one incarnation of the field, no matter how many instances (possibly zero) of the class may eventually be created. A static field, sometimes called a class variable, is incarnated when the class is initialized
So this answers your first question. i.e.e exactly when the class is loaded :)
As per second question, nope. if the variable is declared private. Then the only access is via the method because of encapsulation.
Static variables lasts till the JVM is shutdown.
counter is not a private variable. So it is possible that this value is changed by some other class.
This variable will get reset whenever your program (or specifically the container/jvm) is restated.
1) The variable is set(reset) when the class is loaded. Apart from shutting down the JVM, some servers load the class in different applications (v.g., the Tomcat webapps) and some of them allow restarting them.
2) Concurrent modification by threads. But it should be rare, unless you use it a lot. Use synchronized for the function/block.
The question is when will this variable reset?
static variable can be reset using custom reset() method. If You say restart program, theoretically that variable will be initialized to it's value not reinitialized as it is not same(you restart program).
class Foo { // in same package
public static void main(String[] args) {
Whatever w = new Whatever();
for (int i = 0; i < 1000; i++) {
w.do();
}
Whatever.counter = -1;
}
here do() is invoked 1000 times, but counter will have value at the end.
I used do() like you in your example, but note that is not a valid method name, because it's the keyword for a do while loop.
A static variable means that there are only one incarnation of that field during a program execution. It is loaded when the class is initialized.
For your second question, your variable isn't thread safe because multiple threads can access it at the same time.
Even if your counter was volatile you would still face concurrency problem.
You have three options, given your example and requirements:
If your only requirement is to manipulate the variable and the rest of the code won't depend of that you can use synchronize (killing a fly with a cannon) or AtomicInteger (the choice with better performance):
static synchronize int counter = 0;
// or
static AtomicInteger counter = new AtomicInteger();
If the rest of your code is dependent of your counter, you must use a lock object or synchronize your method:
class Whatever {
static int counter = 0;
synchronize function do() {
counter++;
if(counter < 10){
// do something
}
}
}
// or
class Whatever {
static int counter = 0;
static final Object _lock = new Object();
function do() {
synchronized (_lock) {
counter++;
if(counter < 10){
// do something
}
}
}
}
This are the options that are in my head right now, but probably there are more.
The following method does not work because the inner block declares a variable of the same name as one in the outer block. Apparently variables belong to the method or class in which they are declared, not to the block in which they are declared, so I therefore can't write a short little temporary block for debugging that happens to push a variable in the outer scope off into shadow just for a moment:
void methodName() {
int i = 7;
for (int j = 0; j < 10; j++) {
int i = j * 2;
}
}
Almost every block-scoped language I've ever used supported this, including trivial little languages that I wrote interpreters and compilers for in school. Perl can do this, as can Scheme, and even C. Even PL/SQL supports this!
What's the rationale for this design decision for Java?
Edit: as somebody pointed out, Java does have block-scoping. What's the name for the concept I'm asking about? I wish I could remember more from those language-design classes. :)
Well, strictly speaking, Java does have block-scoped variable declarations; so this is an error:
void methodName() {
for (int j = 0; j < 10; j++) {
int i = j * 2;
}
System.out.println(i); // error
}
Because 'i' doesn't exist outside the for block.
The problem is that Java doesn't allow you to create a variable with the same name of another variable that was declared in an outer block of the same method. As other people have said, supposedly this was done to prevent bugs that are hard to identify.
Because it's not uncommon for writers to do this intentionally and then totally screw it up by forgetting that there are now two variables with the same name. They change the inner variable name, but leave code that uses the variable, which now unintentially uses the previously-shadowed variable. This results in a program that still compiles, but executes buggily.
Similarly, it's not uncommon to accidentally shadow variables and change the program's behavior. Unknowingly shadowing an existing variable can change the program as easily as unshadowing a variable as I mentioned above.
There's so little benefit to allowing this shadowing that they ruled it out as too dangerous. Seriously, just call your new variable something else and the problem goes away.
I believe the rationale is that most of the time, that isn't intentional, it is a programming or logic flaw.
in an example as trivial as yours, its obvious, but in a large block of code, accidentally redeclaring a variable may not be obvious.
ETA: it might also be related to exception handling in java. i thought part of this question was discussed in a question related to why variables declared in a try section were not available in the catch/finally scopes.
It leads to bugs that are hard to spot, I guess. It's similar in C#.
Pascal does not support this, since you have to declare variables above the function body.
The underlying assumption in this question is wrong.
Java does have block-level scope. But it also has a hierarchy of scope, which is why you can reference i within the for loop, but not j outside of the for loop.
public void methodName() {
int i = 7;
for (int j = 0; j < 10; j++) {
i = j * 2;
}
//this would cause a compilation error!
j++;
}
I can't for the life of me figure out why you would want scoping to behave any other way. It'd be impossible to determine which i you were referring to inside the for loop, and I'd bet chances are 99.999% of the time you want to refer to the i inside the method.
another reason: if this kind of variable declaration were allowed, people would want (need?) a way to access outer block variables. may be something like "outer" keyword would be added:
void methodName() {
int i = 7;
for (int j = 0; j < 10; j++) {
int i = outer.i * 2;
if(i > 10) {
int i = outer.outer.i * 2 + outer.i;
}
}
}