Increment a variable without using static keyword - java

Here I am using static keyword to instantiate a variable And I am calling the variable using two different Objects.I want to print the result as 1 and 2 without using the static keyword.Thanks in advance.
public class Test {
static int a = 1;
public void meth() {
System.out.println(a);
a = a + 1;
}
public static void main(String[] args) {
Test a = new Test();
Test b = new Test();
a.meth(); //prints 1
b.meth(); //prints 2
}
}

If you remove the static keyword, you need to share an int variable in your two instances of Test.
For example, using AtomicInteger as a mutable wrapper for int and providing the object when constructing Test:
public class Test {
private final AtomicInteger a;
// + constructor setting a + getter
public void increment() {
a.incrementAndGet();
}
}
public class Main {
public static void main(String[] args) {
AtomicInteger i = new AtomicInteger()
Test a = new Test(i);
Test b = new Test(i);
System.out.println(i.get()); // prints 0
a.increment();
System.out.println(i.get()); // prints 1
b.increment();
System.out.println(i.get()); // prints 2
}
}

Related

How do I execute the function public method declared inside a class which is in turn inside a private method?

So, I want to execute the sum() of the following block of code:
import java.lang.reflect.Method;
public class LocalOuterClass { // start of outer
private int x = 10;
private Object run() { //start of inner
class LocalInnerClass {
private int y = 20;
public void sum() {
System.out.println(x+y);
}
} //end of inner
LocalInnerClass lc = new LocalInnerClass();
//lc.sum();
return lc;
}
public static void main(String[] args) {
LocalOuterClass Loc = new LocalOuterClass();
Object obj = Loc.run();
System.out.println(obj.getClass());
Method[] methods = obj.getClass().getMethods();
for (Method method : methods) {
String MethodName = method.getName();
System.out.println("Name of the method: "+ MethodName);
}
}
} //end of outer
When I do lc.sum(), the sum() is correctly executed. But when I'm returning an object of the inner class to the main() and try to execute sum(), it gives a compiler error. Doing getClass().getMethods() on the object does print sum() as one of the methods. What should I do to execute the sum() inside main()?
You have to change return type to LocalInnerClass and move LocalInnerClass out of the method:
public class LocalOuterClass {
private int x = 10;
private class LocalInnerClass {
private int y = 20;
public void sum() {
System.out.println(x + y);
}
}
private LocalInnerClass run() {
LocalInnerClass lc = new LocalInnerClass();
//lc.sum();
return lc;
}
public static void main(String[] args) {
LocalOuterClass Loc = new LocalOuterClass();
LocalInnerClass obj = Loc.run();
obj.sum(); // it works!
// ...
}
}
The problem is, that the whole LocalInnerClass is not known to your main-method. It does not help, that it has a public method, if the whole type is unknown. You need to refactor your code in order to change that.
Actually your method run currently returns a value of type Object and you'd need to return a value of type LocalInnerClass, however this is not possible due to type visibility.
There are basically two options you have. One is to move the whole LocalInnerClass to a location that is visible to main (like oleg.cherednik suggested):
class LocalOuterClass {
private int x = 10;
private LocalInnerClass run() { // now we can retun `LocalInnerClass`
return new LocalInnerClass();
}
public static void main(String[] args) {
new LocalOuterClass().run().sum(); // works!
}
private class LocalInnerClass {
private int y = 20;
public void sum() {
System.out.println(x+y);
}
}
}
Another option is to implement/extend a different type that has sum, e.g. like this:
class LocalOuterClass {
private int x = 10;
private Summable run() { //start of inner
class LocalInnerClass implements Summable {
private int y = 20;
public void sum() {
System.out.println(x+y);
}
}
return new LocalInnerClass();
}
public static void main(String[] args) {
new LocalOuterClass().run().sum(); // works as well
}
private interface Summable {
void sum();
}
}
With this interface-option the type LocalInnerClass is still not visible to anyone outside your run-method, however the Summable-interface is and since your LocalInnerClass implements Summable you can return a value of that type.

Is there any flaw in the below design ? My intention is whenever an object is created, unique id has to be generated

public class Test {
private static int counter = 1;
int uniqueId;
public Test() {
uniqueId = counter++;
}
public int getUniqueId() {
return uniqueId;
}
}
public class TestSub {
public static void main(String args[]) {
Test a = new Test();
Test b = new Test();
}
}
Assuming that:
the scope of int is large enough for your needs
you will not work with more than one thread at a time
you do not need randomness (for security reasons)
it should do exactly what you're describing.

Doesn't this defy the rules of static variables?

I have declared a static variable and am changing its value through a non-static method by invoking it in the Initializer block which will be invoked every time an object is instantiated. Why does this not give me run time or compile time error?
public class FinalKeyWord {
final int age;
static int name;
{
ran();
displayName();
}
public FinalKeyWord() {
this.age = 10;
}
public FinalKeyWord(int a){
this.age = a;
}
void ran(){
Random r = new Random();
int rand = r.nextInt(6);
System.out.println(rand);
name = rand;
}
public void displayAge() {
System.out.println("This is final " + age);
}
public void displayName() {
System.out.println("This is static " + name);
}
public static void main(String[] args) {
FinalKeyWord a = new FinalKeyWord();
//a.displayAge();
//a.displayName();
FinalKeyWord a2 = new FinalKeyWord(35);
//a2.displayName();
}
}
Output:
This is static 2 \n
This is is static 3
a variable being static doesn't mean that you can't change its value later, it means that its allocated once in memory for all instances of the class its in, so whenever you create an new object it will point to the same block in memory for this variable unlike normal variables or instance variables where a new block in memory will be reserved for this variable whenever a new object of this class is created.
From Java Documentation/Tutorials,
Instance methods can access class variables and class methods directly.
So this is perfectly legal,
public class FinalKeyWord {
static int a = 5;
void change() {
a= 10;
}
public static void main(String[] args) {
FinalKeyWord obj = new FinalKeyWord();
System.out.println(a);
obj.change();
System.out.println(a);
}
}
And will print,
5
10

Output ID of instance

I want to create 5 instances of a class, but no more (error message when instantiated 6th time). Also I want to be able to call each objects fields(id in this case) in custom order, so I need reference variables for those objects which I don't because my getInstance() had to be a static method. How can I output the id's of each object for example in reverse order they were created. Hope this makes sense, if not just tell me how you would normally do this kind of stuff.
public class JustFive {
private static int i=0;
private int id;
public JustFive(int n){
this.id=n;
}
public static void main(String[] args) throws Exception {
getInstance();
getInstance();
getInstance();
getInstance();
getInstance();
}
private static JustFive getInstance() throws Exception{
if(i<5) {
i++;
System.out.println(i+" instance created ");
return new JustFive(i*1000);
} else
throw new Exception("Can't create more than 5 instances of this class");
}
private int getId(){
return this.id;
}
}
Create five JustFive instances, place them in a List<JustFive>, then use a Comparator<JustFive> to sort them in descending order by id.
public static void main(String[] args) throws Exception {
List<JustFive> jfs = Arrays.asList(getInstance(), getInstance(), getInstance(), getInstance(), getInstance());
Collections.sort(jfs, new Comparator<JustFive>(){
#Override
public int compare(JustFive o1, JustFive o2) {
return -1 * new Integer(o1.id).compareTo(o2.getId());
}
});
for (JustFive justFive : jfs) {
System.out.println(justFive.getId());
}
}
Outputs
1 instance created
2 instance created
3 instance created
4 instance created
5 instance created
5000
4000
3000
2000
1000
import java.util.List;
public static void main(String[] args) throws Exception {
List<JustFive> elems = new ArrayList<>();
for (int i = 0; i < 5; i++) {
elems.add(getInstance());
}
// print in reverse order
for (int i = elems.size() - 1; i >= 0; i--) {
System.out.println(elems.get(i).getId());
}
}

Using Objects in a similar way to Variables in Java

Can i use the following code? It's not throwing any error at the Object but at obj.i. Is this a legal way of using an object? Also, how many ways can i create an object other than using the normal syntax obj s = new obj();
public class Test {
static int i;
static Test obj;
obj.i = 10; //am getting a compilation error here "Syntax error on token "i", VariableDeclaratorId expected after this token"
public static void main(String[] args) {
System.out.println(i+" "+ obj);
}
}
You need to place a static block around the obj.i assignment statement for this to work:
public class Test {
static int i;
static Test obj;
static { obj.i = 10; }
public static void main(String[] args) {
System.out.println(i+" "+ obj);
}
}
This is not, you didn't initialize. Furthermore you might not want to use static.
public static void main(String [] args) {
int i = 10;
Test obj = new Test();
obj.setI(i);
System.out.println("my objects I = "+ obj.getI());
}
now in your Test object
public class Test {
private int i;
public void setI(int i) {
this.i = i;
}
public int getI() {
return this.i;
}
}

Categories

Resources