Accessing a variable globally (Java) - java

I'm developing an application for Android, and at one point the user chooses a region, after which the contents of all parts of the app is changed. Therefore I need to access an integer throughout the program. I have considered a singleton class, but I can't figure out how to add just an int, a get() and a set() to it (I want to be able to read everywhere and write in two classes(everywhere is fine)).
Should I simply declare it global?
This is what I've got going now, is it ok?
public enum Region {
INSTANCE;
private int rID =0;
public void setRID(int rID) {
this.rID=rID;
}
public int getRID()
{
return rID;
}
}
To be accessed with
Region.INSTANCE.setRID(5);

Try something like
public class State
{
static State instance = new State ();
public static State getInstance() { return instance; }
private int value;
public void setValue (int value) { this.value = value; }
public int getValue () { return value; }
}
Don't forget to store your value when your application exits, and restore it when it reloads.

This is not really a Singleton, but a static class. A class that contains a static field (a field not bounded to an instance):
public class StaticClass {
private static int value;
private Singleton () {}
public static int getValue () {
return value;
}
public static void setValue (int val) {
value = val;
}
}
you can access the value by StaticClass.getValue() and set the value by StaticClass.getValue(4). ('StaticClass must not be replaced by an object).
The private constructor prevents one to create an instance by accident.

Create a public static class and declare the setter and getter as public.

I went with an enum:
public enum Region {
INSTANCE;
private int rID =0;
public void setRID(int rID)
{
this.rID=rID;
}
public int getRID()
{
return rID;
}
}
Which I access with
Region.INSTANCE.getRID();

Related

Java visible interface that can not be implemented

I'm working on making a programming language that compiles to JVM bytecode, and it highly relies on interfaces as types. I need some way to make an interface private, but have other code still be able to access it, but not make something that implements it.
I was thinking about using abstract classes with a private constructor, so only the classes in the same file would be able to access it. The only problem is that it is impossible to extend multiple abstract classes at once. For example, the structure of a simple compiled program would be this:
// -> Main.java
public class Main {
public static MyInteger getMyInteger() {
return new MyIntegerImpl(10);
}
public static void main(String[] args) {}
private interface MyInteger {
public int getValue();
}
private static class MyIntegerImpl implements MyInteger {
private final int value;
public int getValue() {
return value;
}
public MyIntegerImpl(int value) {
this.value = value;
}
}
}
And another file, in which there is a problem:
// -> OtherFile.java
public class OtherFile {
public static void main(String[] args) {
Main.MyInteger myInteger = Main.getMyInteger(); //Error: The type Main.MyInteger is not visible.
System.out.println(myInteger.getValue());
}
//I do not want this to be allowed
public static class sneakyInteger implements Main.MyInteger { //Error(Which is good)
public int getValue() {
System.out.println("Person accessed value");
return 10;
}
}
}
The reason why I want to do this is so one person can not mess up any other person's code by providing their own implementations of things that should be only implemented by that other person.
Any help would be much appreciated.
I'm pretty sure that you should think again about what you are trying to do and change approach, but the answer for your question is to add to the interface some empty void method that is getting the parameter of the inner private class specific for the wrapper class
public class Test {
private class InnerPrivateClass {
private InnerPrivateClass() {}
}
public interface MyInteger {
int getValue();
void accept(InnerPrivateClass c);
}
private class MyIntegerImpl implements MyInteger {
#Override
public int getValue() {
return 0;
}
#Override
public void accept(InnerPrivateClass c) {}
}
}
However, as I said, I don't like this and for me it means that your idea is broken

Accessibility between objects (instances) of the same class

When one object of a class has a reference to another object of
the same class, the first object can access all the second object’s
data and methods (including those that are private).
I took this sentence from a book. But I couldn't figure out actually what it means.
It means that private members are visible to other instances of the same class. For example:
class A {
private int v;
public boolean isSameV(A other) {
return this.v == other.v; // can acccess other.v
}
}
It means that if you have a class that looks like this
public class A {
private int number;
private A otherInstance;
public int number2;
public void DoStuff() {
...
}
}
you can access A.number in the DoStuff method (or any other class method) even although number is actually private.
e.g.
public class A {
...
public void DoStuff() {
this.otherInstance.number = 42;
^^^^^^^
cannot access private members here
}
}
is perfectly fine, while
public class B {
private A aInstance;
public void DoStuffToo() {
this.aInstance.number = 42;
}
}
would not compile, because B cannot access A's private members.
Good question actually, I faced similar problem when I started learning Java, here is how it looks in practice:
public class A {
private String example;
protected int anotherOne;
public A(){
}
public A(A a){
this.example = a.example; // here we get access to private member of another object of same class
this.anotherOne = a.anotherOne; // it works for protected as well
}
// This works for methods not just constructor, lets consider we want to swap value of example:
public void swapExample(A a){
String temp = a.example;
a.example = this.example;
this.example = temp;
}
}
Private fields can be accessed from inside of the class, by this construction you can access all the field of an instance of Foo without getters and setters when you are in class Foo :
public class Foo {
private String name;
public int sumLetter(Foo b) {
return this.name.length() + b.name.length();
}
}
The doc : Declaring Member Variables :
private modifier — the field is accessible only within its own class.

Make instance accessible by only one thread at the time?

I have a java class:
class Card {
private static Card instance = new Card();
public int value:
private Card() {}
public static Card sharedInstange() {
return instance;
}
}
This class models a shared instance which can be access by different threads. The instance variable value therefor must be synchronized such that only one thread can read and write it at a time.
How can I achieve that my instance variables of the Card class can only accessed by one thread at the time?
Edit: Here is the same class with getter and setter.
class Card {
private static Card instance = new Card();
private int value:
private Card() {}
public static Card sharedInstange() {
return instance;
}
public int getValue() { return value; }
public void setValue(int v) { this.value = v; }
}
Make it volatile and create getters/setters without synchronized keyword.
Or just make it AtomicInteger.

How does a static method use a comparator?

I have a static method which needs to invoke the SportsMenComparator. But this, as we all know is not allowed. How does a static function use a comparator subclass ? Although I have workarounds, I am looking for best practices for this particular problem.
final class SportsMan {
private final String name;
private final int rank;
private final String sport;
public SportsMan (String name, int rank, String sport) {
this.name = name;
this.rank = rank;
this.sport = sport;
}
public String getName() {
return name;
}
public int getRank() {
return rank;
}
public String getSport() {
return sport;
}
}
final class Sport {
private final String sport;
private final int numberOfPlayers;
public Sport(String sport, int numberOfPlayers) {
this.sport = sport;
this.numberOfPlayers = numberOfPlayers;
}
public String getSport() {
return sport;
}
public int getNumberOfPlayers() {
return numberOfPlayers;
}
}
public final class Joins {
private Joins () {}
public class SportsMenComparator implements Comparator<SportsMan> {
#Override
public int compare(SportsMan s1, SportsMan s2) {
return s1.getSport().compareTo(s2.getSport());
}
}
public static void innerJoinSort(List<SportsMan> sportsMans, List<Sport> sportList) {
Collections.sort(sportsMans, new SportsMenComparator());
}
}
Eclipse results in the following message: No enclosing instance of type Joins is accessible where Joins is name of the enclosing class.
But this, as we all know is not allowed. How does a static function use a comparator subclass ?
You cannot use a non static reference,still you are allowed to create a new object and use it. So since you are creating a new SportsMenComparator object and passing, no issues.
For example:
public static void main(String[] args) {
List<String> s =new ArrayList<String>();
s.add(""); // allowed
}
But
List<String> s =new ArrayList<String>();
public static void main(String[] args) {
System.out.println();
s.add(""); // Error: Cannot make a static reference to the non-static field s
}
Edit:
Since you defined the comparator class inside the Joins , you need the Joins object to access the comparation inside it
Collections.sort(sportsMans, new Joins().new SportsMenComparator());
For using a Comparator, there is no difference between using it from a static- or non-static method. In either case an instance of the Comparator has to be used.
The Garbage Collector of modern JVMs is very efficient at handling short-lived objects. Therefore the penalty to be paid for using a fresh instance (via new) every time is usually no issue. However, if you don't want to use a fresh instance every time, I think the best option would be to add a static field to your SportsMenComparator, containing a singleton instance of the comparator:
public class SportsMenComparator implements Comparator<SportsMan> {
public static final SportsMenComparator instance=new SportsMenComparator();
#Override
public int compare(SportsMan s1, SportsMan s2) {
return s1.getSport().compareTo(s2.getSport());
}
}
public static void innerJoinSort(List<SportsMan> sportsMans, List<Sport> sportList) {
Collections.sort(sportsMans, SportsMenComparator.instance);
}
The problem is that you try to access an instance element (in this case it is a class, indeed the same as with a filed or method) within a static method, which is not associated with an instance. SURESH ATTA's answer is right, but you can also make your SportsMenComparator class static and it will work. I do not sse any reason to associate your comparator with an instance of the Joins class.
One can use something like this---
public static boolean someMethod(MyObject obj1, MyObject obj2){
return obj1.compare(obj2);
}
Why you cant include parameter to the function.
public static void innerJoinSort(List<SportsMan> sportsMans, List<Sport> sportList, Comparator comparator) {
Collections.sort(sportsMans, comparator);
}

How to declare field inside Enum in Java?

I want to declare static(or not static) variable inside Enum. I need this because I want to associate enum values with some strings. But i Don't want to hardcode this strings. I want to use my application-wide class with String constants.
I.e. I want to write like this inside enum declaraton, but there compile time error:
public enum MyEnum {
private static final AppConstants CONSTANTS = AppConstants.getInstance();
ONE(CONSTANTS.one()),
TWO(CONSTANTS.two());
}
How I can put in enum a field?
It's one of the limitations, the enum values must be specified first but you can always refer to the same singelton in every instantiation...
enum MyEnum {
ONE(Test.getInstance().one()),
TWO(Test.getInstance().two());
public final String val;
MyEnum(String val) { this.val = val; }
}
Example that outputs "hello":
public class Test {
public static void main(String[] args) {
System.out.println(MyEnum.ONE.val);
}
public String one() {
return "hello";
}
public String two() {
return "world" ;
}
static Test instance;
public synchronized static Test getInstance() {
if (instance == null)
instance = new Test();
return instance;
}
}
It's a bit hacky. But you'll have to change your AppConstants class a bit.
public enum MyEnum {
ONE(getConstant("one")),
TWO(getConstant("one"));
private static final AppConstants CONSTANTS = AppConstants.getInstance();
private static String getConstant(String key) {
// You can use a map inside the AppConstants or you can
// invoke the right method using reflection. Up to you.
return CONSTANTS.get(key);
}
private MyEnum(String value) {
}
}
The enum constants need to be the first elements in the Enumeration
public enum MyEnum {
ONE,TWO;
private static final AppConstants CONSTANTS = AppConstants.getInstance();
#Override
public String toString() {
if(this==ONE){
return CONSTANTS.one();
} else if(this==TWO){
return CONSTANTS.two();
}
return null;
}
}

Categories