Let's say I have a public class with static methods, one of them for example:
public static void test(boolean b){
b = !b;
}
Let's say this class name is Test. From another class, where I have a variable boolean a = false, I call
Test.test(a);
How can I make it change a permanently, and not just change it in that static methods scope?
The only way to make the change permanent is to let the method have a return value and assign it to the variable :
public static boolean test(boolean b){
return !b;
}
a = Test.test(a);
Sounds to me like you are looking for a Mutable Boolean, the simplest of which is an AtomicBoolean.
private void changeIt(AtomicBoolean b) {
b.set(!b.get());
}
public void test() {
AtomicBoolean b = new AtomicBoolean(false);
changeIt(b);
System.out.println(b);
}
Use a static field:
public static boolean flag;
public static void test(boolean b){
flag = !b;
}
Then:
boolean a = true;
Test.test(a);
System.out.println( Test.flag); // false
You can pass an instance to method and use setters to change more variables at once.
public static void updateData(MyClass instance) {
instance.setX(1);
instance.setY(2);
}
in your Test class you can define the boolean variable as static
public static boolean a;
and outside the class change or access it using Test.a=false; or a=Test.a
and if you need to use methods you can hide the static method with inheritance:
public class HideStatic {
public static void main(String...args){
BaseA base = new ChildB();
base.someMethod();
}
}
class BaseA {
public static void someMethod(){
System.out.println("Parent method");
}
}
class ChildB extends BaseA{
public void someMethod(){
System.out.println("Child method");
}
}
I think you are asking for call by reference. You can get this in Java by using arrays:
public static void test(boolean[] b){
b[0] = !b[0];
}
boolean[] param = new boolean[] {a};
test(param);
a=param[0];
//a changed
This works, but it is ugly. If you need to return more than one value, have a look at the Pair or Tuple structures.
Related
I'm trying to create some system with inner class. My code can be summarized to something like this.
public abstract class A {
public abstract void doSomething();
}
public class B {
public final ArrayList<A> list=new ArrayList<A>();
public B(){
}
}
public class C {
private int i;
public C(B b){
b.list.add(new A(){
public void doSomething(){
i++;
}
});
b.list.add(new A(){
public void doSomething(){
System.out.println(i);
}
});
}
}
public static void main (String[] arg) {
B manager=new B();
new C(manager);
new C(manager);
new C(manager);
}
A is abstract class that will be inherited as inner class (in my original code it is listener class), B is some kind of manager class that hold list of As, and C hold data it's data should be only modified or read by it's inner class and upon initialization it add A to the class B. Code itself works fine. But problem is as there will be various kinds of C something like C2, C3 that does different thing and this leads to my code overwhelmed with thousands of unassigned object new C(manager); this make debugging extra hard and code looks really ugly. So it seems to me my approach in the first place was wrong but have no idea how to avoid this. So how should I change my approach to not have thousands of unassigned objects?
My suggestion is: try not to use constructors to do operations that depend on state (i). Use static functions, and save the state in a separate class (we call it a “context”).
import java.util.ArrayList;
public class Demo {
// A
abstract static class InnerListener {
public abstract void onEvent();
}
// B
static class ListenerManager {
public final ArrayList<InnerListener> listeners = new ArrayList<InnerListener>();
}
static class SideEffectContext {
public int i = 0;
}
// C
static class ListenerUtil {
public static void setupListeners(ListenerManager manager, SideEffectContext context) {
manager.listeners.add(new InnerListener() {
public void onEvent() {
context.i++;
}
});
manager.listeners.add(new InnerListener() {
public void onEvent() {
System.out.println(context.i);
}
});
}
}
public static void main(String[] arg) {
var manager = new ListenerManager();
var ctxA = new SideEffectContext();
var ctxShared = new SideEffectContext();
ListenerUtil.setupListeners(manager, ctxA);
ListenerUtil.setupListeners(manager, ctxShared);
ListenerUtil.setupListeners(manager, ctxShared);
}
}
I have a class defined like:
public class Test {
private String a;
private String b;
public Test(String a, String b) {
super();
this.a = a;
this.b = b;
}
}
At some point I create instances of this class and put them in a List<Test> ArrayList. The problem is sometimes I want a to be of type double not String (i.e. Use another constructor in which a is a double). I'm also interested in always storing the value in a variable called a no matter what. This means creating another instance variable of type double with a different name will not do. It would not be a problem to just make a new class with an instance variable a of type double if it wasn't for the fact that the two classes would not be able to go into the same ArrayList which is also something I need done.
One thing I've seen that could help is to make a List<Object> ArrayList which can hold instances of any class, but I think this is considered bad practice. Any ideas on how I could achieve what I'm trying to do?
While you could do something with generics, that's probably not what you want. There is no bound on the type parameter T, so its type is effectively Object. All you can do is print its value and test for equality, you can't use it in an arithmetic expression (if it's a Double).
public class Test<T> {
private T a;
public Test(T a) {
super();
this.a = a;
}
public void doSomething() {
a.??? // only methods on Object can be called here
}
public static void main(String... args) {
List<Test<?>> tests = new ArrayList<>();
tests.add(new Test<String>("foo"));
tests.add(new Test<Double>(42.0));
}
}
You are probably better off with a type hierarchy, but it depends on what you are actually doing:
public interface Test {
boolean doSomething();
class TestString implements Test {
private final String a;
public TestString(String a) {
this.a = a;
}
#Override
public boolean doSomething() {
return a.contains("foo");
}
}
class TestDouble implements Test {
private final double a;
public TestDouble(double a) {
this.a = a;
}
#Override
public boolean doSomething() {
return a > 10.0;
}
}
static void main(String... args) {
List<Test> tests = new ArrayList<>();
tests.add(new TestString("foo"));
tests.add(new TestDouble(42.0));
}
}
The boolean has to be outside the main method so other methods can manipulate it. I've searched everywhere and cannot find a suitable answer because all I stumble upon are solutions for booleans as methods. It has to be a simple boolean and it cannot be static. Don't have much time, so any help would be great. Thanks.
public class myClass {
private int[][] holdsStuff;
private boolean isNeeded;
public setFalse (){
}
public setTrue () {
}
public static void main(String[] args) {
//call methods to change isNeeded
//require isNeeded to prevent invalid changes being made to holdsStuff
}
}
If class member isNeeded is not static, then it must belong to an instance of myclass, you can create a new instance and manipulate this instance:
public class myClass {
private int[][] holdsStuff;
private boolean isNeeded;
public void setFalse (){
isNeeded = false;
}
public void setTrue () {
isNeeded = true;
}
public static void main(String[] args) {
myClass mc = new myClass();
myClass.setFalse();
}
}
You want to use isNeeded in other methods and in main method which is static and static methods just deal with static data read this. so what you want to do is make instance of this class to call isNeeded in main method
public static void main(String[] args) {
myClass myclass = new myClass();
boolean isNeeded = myclass.isNeeded;
}
public class myClass {
private int[][] holdsStuff;
private boolean isNeeded;
public void setFalse (){
isNeeded =false;
}
public void setTrue () {
isNeeded = true;
}
public static void main(String[] args) {
myClass myclass = new myClass();
myclass.setFalse();
myclass.setTrue();
//call methods to change isNeeded
//require isNeeded to prevent invalid changes being made to holdsStuff
}
}
since main is static either use static keyward or make an instance of the same class. use static key the following:
public class myClass {
private int[][] holdsStuff; // make this static if you are also this inside main
private static boolean isNeeded;
public static setFalse (){
}
public static setTrue () {
}
public static void main(String[] args) {
//call methods to change isNeeded
//require isNeeded to prevent invalid changes being made to holdsStuff
}
}
I got the object wolfOne of the Class Wolf, and I need to access to its variable mAlive in another Class, how may I don it?
Wolf wolfOne;
//Wolf Class
public class Wolf extends Card {
public Wolf(){
mCharacter = "Wolf";
}
public void savage(Card card) {
card.mAlive = false;
}
}
//Card Class
public class Card {
//Names
public String mCharacter;
//Status
public static boolean mAlive;
public static boolean mDefended;
public static boolean mOwled;
public static boolean mLastSavaged;
public static boolean mLastLynched;
//Constructor
public Card() {
// Do Card specific stuff.
}
}
Remove static from all of your Class variables - make them instance variables instead. Then provide typical getters/setters for each, allowing clients of the class to retrieve or mutate the value:
public class Wolf extends Card {
public Wolf(){
setMCharacter("Wolf");
}
public void savage(Card card) {
card.setMAlive(false);
}
}
public class Card {
//Names
private String mCharacter;
//Status
private boolean mAlive;
private boolean mDefended;
private static boolean mOwled;
private static boolean mLastSavaged;
private static boolean mLastLynched;
public String getMCharacter(){}
return mCharacter;
}
public void setMCharacter(String value){
this.mCharacter = value;
}
public boolean getMAlive(){
return mAlive;
}
public void setMAlive(boolean alive){
this.mAlive = alive
}
//....So on and so forth
}
static has a special meaning in Java. It doesn't mean that the variable or method is inheritable; it means that there is only one of it that belongs to the class, not the instance.
To inherit from a super class, all that is required is that it not private and the inheriting classes will get it. The following example shows this relationship.
import java.util.*;
import java.lang.*;
import java.io.*;
class A
{
public String name;
public boolean isAlive;
public A()
{
name = "A";
isAlive = true;
}
}
class B extends A
{
public B()
{
name = "B";
isAlive = false;
}
}
public class Main
{
public static void main (String[] args)
{
A a = new A();
A b1 = new B();
B b2 = new B();
b2.name = "B2";
b2.isAlive = true;
System.out.println(a.name);
System.out.println(a.isAlive);
System.out.println(b1.name);
System.out.println(b1.isAlive);
System.out.println(b2.name);
System.out.println(b2.isAlive);
}
}
And gives this output:
A
true
B
false
B2
true
This can be run here.
In the card class make the fields private not public, in oo this is called encapsulation or data hiding (look it up). Then simply add a getMAlive method that returns the mAlive value and a setMAlive method which will set it. Now in your wolf class to set mAlive you can with setMAlive(boolean). For external objects you will need to have a reference to your wolf/card and call wolfName.getMAlive()
For card...
private boolean mAlive;
public boolean getMAlive(){
return mAlive;
}
public void setMAlive(boolean value){
mAlive = value;
}
For wolf...
public void savage(){
setMAlive(false);
}
For other classes to get mAlive...
wolfName.getMAlive()
You may consider making your mAlive (and other fields in Card) protected. Protected fields can only be seen by those classes that extend them e.g. wolf. So in wolfs savage method you could do...
public void savage(){
mAlive = false;
}
But to set mAlive from other classes you would still need a setter in Card so yeah
I hope this helps :) good luck
public class Test {
public static void main(String[] args) {
DemoAbstractClass abstractClass = new DemoAbstractClass() {
private String val;
#Override
public void runner() {
val = "test";
System.out.println(val);
this.run();
}
public String getVal() {
return val;
}
};
abstractClass.runner();
/**
* I want to access getVal method here
*/
}
}
abstract class DemoAbstractClass {
public void run() {
System.out.println("running");
}
public abstract void runner();
}
Here, I'm declaring an abstract class DemoAbstractClass. I can obviously create a new class that extends this class and add this method to it. But, I would prefer not doing that in my scenario.
Is there any other way to access getVal method in above code??
You can't. You need to make a proper (non-anomous) class out of it. Make it an inner private class if you want to limit its scope.
Alternatively, you could use a StringBuffer and share a referense to it between the methods. Not extremely clean however.
Related question:
Accessing inner anonymous class members
Short of using reflection, you cannot as you have no access to the concrete type of the object to be able to bind the methodcall to
If you don want to do something like this in a sane manner, declare a named class and use that as the type of abstractClass
Unfortunately, if you cannot name the type, you cannot access the methods at the language level.
What you can do, though, is use the reflection API to get a Method object and invoke it on this object.
This, however, is pretty slow. A private class or private interface would be much faster.
I can obviously create a new class that extends this class and add this method to it.
You've already done this; the end result was an anonymous inner class: new DemoAbstractClass() { ... }; If you just moved that declaration into its own class -- you can even make it a private class -- you can access getVal.
Per your example above:
public class Test {
public static void main(String[] args) {
DemoClass abstractClass = new DemoClass();
abstractClass.runner();
/**
* I want to access getVal method here
*/
abstractClass.getVal(); // can do this here now
}
private class DemoClass extends DemoAbstractClass {
private String val;
#Override
public void runner() {
val = "test";
System.out.println(val);
this.run();
}
public String getVal() {
return val;
}
}
}
}
Another option is to make a StringBuilder a member of the main method and use the closure nature of anonymous inner methods:
public static void main(String[] args) {
final StringBuilder value = new StringBuilder();
DemoAbstractClass abstractClass = new DemoAbstractClass() {
#Override
public void runner() {
value.append( "test" );
System.out.println(val);
this.run();
}
};
abstractClass.runner();
// use val here...
String val = value.toString();
}