Making a static duplicate of non-static integer - java

For my programming class in first year engineering I have to make a D-game in Java, with only very little knowledge of Java.
In one class I am generating a random integer via
public int rbug = (int)(Math.random() * 18);
every so many ticks. I have to use this integer in another class (in the requirements for an if-loop), and apparently it needs to be static. But when I change the variable to public int static, the value doesn't change any more.
Is there an easy way to solve this problem?
Edit: part of code added:
public int rbug = (int)(Math.random() * 18);
which is used in
public void render(Graphics g){
g.drawImage(bugs.get(rbug), (int)x, (int)y, null);
And in another class:
if(Physics.Collision(this, game.eb, i, BadBug.rbug)){
}
As error for BadBug.rbug I get the message
Cannot make a static reference to a non-static field

Using static to make things easier to access is not a very good ideal for design. You would want to make variables have a "getter" to access them from another class' instance, and possibly even a "setter". An example of this:
public class Test {
String sample = 1337;
public Test(int value) {
this.sample = value;
}
public Test(){}
public int getSample() {
return this.sample;
}
public void setSample(int setter) {
this.sample = setter;
}
}
An example of how these are used:
Test example = new Test();
System.out.println(example.getSample()); // Prints: 1337
example = new Test(-1);
System.out.println(example.getSample()); // Prints: -1
example.setSample(12345);
System.out.println(example.getSample()); // Prints: 12345
Now you might be thinking "How do I get a string from the class that made the instance variable within the class?". That's simple as well, when you construct a class, you can pass a value of the class instance itself to the constructor of the class:
public class Project {
private TestTwo example;
public void onEnable() {
this.example = new TestTwo(this);
this.example.printFromProject();
}
public int getSample() {
return 1337;
}
}
public class TestTwo {
private final Project project;
public TestTwo(Project project) {
this.project = project;
}
public void printFromProject() {
System.out.println(this.project.getSample());
}
}
This allows you to keep single instances of classes by passing around your main class instance.
To answer the question about the "static accessor", that can also be done like this:
public class Test {
public static int someGlobal = /* default value */;
}
Which allows setting and getting values through Test.someGlobal. Note however that I would still say that this is a horrible practice.

Do you want to get a new number every time that you want BadBug.rbug? Then convert it from a variable to a method.

Related

Return a Reference to a Class with Static Methods and Static Fields Without Instantiation

I want to create a wrapper class that calls static methods and member fields from a class that is provided by a library I am unable to view the code.
This is to avoid boilerplate setting code of the global member fields when I need to use a static method in a specific context.
I want to try to avoid creating wrapper methods for each static method.
My question:
Is it possible to return a class with static methods from a method to access just the static methods without instantiating it?
Code is below with comments in-line.
The code is used to demonstrate a change in a static value when the method getMath() is invoked.
I want to avoid the setting of the value before calling the static method.
StaticMath.setFirstNumber(1);
StaticMath.calc(1);
StaticMath.setFirstNumber(2);
StaticMath.calc(1);
I am using the Eclipse IDE and it comes up with Warnings, which I understand, but want to avoid.
I tried searching for something on this subject, so if anyone can provide a link I can close this.
public class Demo {
// Static Methods in a class library I don't have access to.
static class StaticMath {
private static int firstNum;
private StaticMath() {
}
public static int calc(int secondNum) {
return firstNum + secondNum;
}
public static void setFirstNumber(int firstNum) {
StaticMath.firstNum = firstNum;
}
}
// Concrete Class
static class MathBook {
private int firstNum;
public MathBook(int firstNum) {
this.firstNum = firstNum;
}
// Non-static method that gets the class with the static methods.
public StaticMath getMath() {
StaticMath.setFirstNumber(firstNum);
// I don't want to instantiate the class.
return new StaticMath();
}
}
public static void main(String... args) {
MathBook m1 = new MathBook(1);
MathBook m2 = new MathBook(2);
// I want to avoid the "static-access" warning.
// Answer is 2
System.out.println(String.valueOf(m1.getMath().calc(1)));
// Answer is 3
System.out.println(String.valueOf(m2.getMath().calc(1)));
}
}
I'd just wrap it to make for an atomic operation:
public static class MyMath{
public static synchronized int myCalc( int num1 , int num2 ){
StaticMath.setFirstNum(num1);
return StaticMath.calc(num2);
}
}
Drawback: You'll have to make sure, StaticMath is not used avoiding this "bridging" class.
Usage:
int result1 = MyMath.myCalc( 1, 1 );
int result1 = MyMath.myCalc( 2, 1 );
You shouldnt call a static method through an object reference. You should directly use class reference to call a static method like this:
StaticMath.calc(1)
But if you still need it for some reason, you can return null in getMath method, but you will still get warning in Eclipse:
public StaticMath getMath() {
StaticMath.setFirstNumber(firstNum);
return null;
}
I infer that question is not properly asked if the answer is not
StaticMath.calc(1)
Other issue you may be facing due to package visibility to static inner classes. Which is a design choice by the writer of Demo class. If you can mark your classes MathBook and StaticMath public then you can access them like below:
Demo.StaticMath.calc(1);

Constructor call is giving error-Inheritance

In a child class GreenSlime Im given a constructor with only three parameters (I cannot add any other instance variables). But the code keeps giving error about this line:super(loc,map,log); which I understand that the constructor should have the same amount of parameters. But my specs say that via the parent constructor, sets all fields. fullcharge must always be 4, and the starting value for charge is 0. I do know that I'm passing only 3 parameters instead of 5, but that's the instructions of my project say so. What am I doing wrong and what's the best approach/solution?
import java.io.PrintStream;
public class GreenSlime extends Threat {
public GreenSlime(Coord loc, Map map, PrintStream log)
{
super(loc,map,log);
super.fullCharge = 4;
super.charge = 0;
}
}
import java.io.PrintStream;
public abstract class Threat extends Thing {
protected int charge;
protected final int fullCharge;
public Threat(Coord c, String repr, int fullCharge, Map map, PrintStream log)
{
super(c,repr,map,log);
this.fullCharge = fullCharge;
charge = 0;
}
public abstract void spawn(Coord c);
#Override
public void doAction()
{
while(charge != fullCharge)
{
System.out.println("\"+repr()"+"#"+"getLoc()\" speading");
if(this.canPassThrough())
{
spawn(getPrevLoc().step(Direction.N));
spawn(getPrevLoc().step(Direction.S));
spawn(getPrevLoc().step(Direction.E));
spawn(getPrevLoc().step(Direction.W));
}
charge++;
}
}
}
public GreenSlime(Coord loc, Map map, PrintStream log)
{
super(loc,"",4,map,log);
}
I've supplied an empty string "" for repr, but you may need null or some other value.
In your code, the Threat constructor has a signature that accepts 5 arguments, but where as you're trying to pass only 3 arguments to it.

Pass an object of another class to a singleton class

I am using this singleton class in Java and in one method, I need an object of a class which gets instantiated in Main. I am not knowing how to pass that object to this method because this code is written in the constructor of the singleton class as I need it to be executed as soon as the program starts.
Should I take out the code from the constructor and make it a standalone method which I call from Main (though I wouldn't prefer this) or is there another way?
Any ideas?
Code:
Main:
public static void main(String[] args) {
X x; // This is the object I need to pass to the singleton class
}
Singleton class:
public SomeSingletonClass {
private Queue<Y> someQueue; // Y is another class I have in my project
private SomeSingletonClass(){
someQueue.add(new Y(<some data>, <some data>, <here I need an object of X as the constructor needs it>);
}
}
I haven't added the entire code. Just a fragment where I am stuck.
You have two main options.
The first will produce howls of derision - and rightly so because it is a dark tunnel of hell.
public class X {
}
public class Y {
public Y(String s, X x) {
}
}
public class Main {
public static X x = new X();
}
public class SomeSingletonClass {
private Queue<Y> someQueue = new LinkedList<>();;
private SomeSingletonClass() {
someQueue.add(new Y("Hello", Main.x));
}
}
Here we make the X created by Main a public static so it is now, essentially, global state in parallel with your singleton.
Most readers will understand how nasty this is but it is the simplest solution and therefore often the one taken.
The second option is lazy construction.
public class BetterSingletonClass {
private BetterSingletonClass me = null;
private Queue<Y> someQueue = new LinkedList<>();
private BetterSingletonClass(X x) {
someQueue.add(new Y("Hello", x));
}
public BetterSingletonClass getInstance (X x) {
if ( me == null ) {
me = new BetterSingletonClass(x);
}
return me;
}
}
Note that I have made no effort to make this a real singleton, n'or is this thread-safe. You can search for thread safe singleton elsewhere for plenty of examples.

How to structure following requirements in JAVA classes

Scenario is like this:
There is a field in database 'overAllCount' which contains some value.
I have to use this variable in many classes I am designing.
I want to fetch this 'overAllCount' in one class say 'OverAllCountClass' and use it in all subclasses with its class name like OverAllCountClass.overAllCount. Basically like a static variable.
How can I do it?
My solution is:
public Class OverAllCountClass {
public static int OverAllCount;
public OverAllCountClass(){
// Fetch overAllCount from database here and set its value
}
}
////////// Use it like this //////////////
public class Usecount {
public void abc(){
// BUT IT IS NOT POSSIBLE becuase OverAllCountClass is not yet initialize
int mycount = OverAllCountClass.overAllCount
}
}
How can I achieve this?
If your concern is, the static variable overAllCount, might not get initialized and if you want it to get initialized whenever the class OverAllCountClass first gets invoked, then you can use Static initializer blocks
public class OverAllCountClass {
public static int overAllCount;
static {
overAllCount = fetchOverAllCount();
}
}
A static initializer block is invoked first time a class gets loaded. And a class gets first loaded when JVM sees that its been used.
public class Usecount {
public void abc(){
//When JVM sees that OberAllCountClass is used here, it executes the static block of OverAllCountClass and by the time below statement is executed, overAllCount is initialized
int mycount = OverAllCountClass.overAllCount
}
}
public Class OverAllCountClass {
protected int overAllCount; //will allow you to use in subclass too
public OverAllCountClass(){
// Fetch overAllCount from database here and set its value
}
public int getOverAllCount(){
return overAllCount;
}
}
public class Usecount {
//pass the instance of overAllCountInstance to UseCount somehow using constructor or setter
private OverAllCountClass overAllCountInstance;
public void abc(){
int mycount = overAllCountInstance.getOverAllCount();
}
}
No need to use static over here. Use getter to get the count
Rather than having a public static variable which can be modified/abused by other classes. I would provide a specific API which can hide the implementation and do things like lazy-loading if needed:
public static final Value getValue(){
//evaluate private field
return value;
}
This API can be a static method or be a singleton scoped method, depending on use case.
Another option is to make OverAllCountClass a Singleton.
public class OverAllCountClass {
private static final OverAllCountClass instance = new OverAllCountClass();
private Integer overAllCount = null;
// make it non-instanciable outside by making the constructor private
private OverAllCountClass {
}
public static OverAllCountClass getInstance() {
return instance;
}
public int getOverAllCount() {
if (overAllCount = null) {
//get value from database and assign it
}
return overAllCount;
}
}
This has the benefit that to code that accesses OverAllCountClass it is transparent wether it's a Singleton or not. This makes swapping out the implementation easier.

How to call a public method WITHIN a private attribute?

I am new to Java. So the question may seem naive... But could you please help?
Say for example, I have a class as follows:
public class Human {
private float height;
private float weight;
private float hairLength;
private HairState hairTooLong = new HairState() {
#Override
public void cut(Human paramHuman) {
Human.this.decreaseHairLength();
}
#Override
public void notCut(Human paramHuman) {
Human.this.increaseHairLength();
}
};
public float increaseHairLength () {
hairLength += 10;
}
public float decreaseHairLength () {
hairLength -= 10;
}
private static abstract interface HairState {
public abstract void cut(Human paramHuman);
public abstract void notCut(Human paramHuman);
}
}
Then I have another class as follow:
public class Demo {
public static void main(String[] args) {
Human human1 = new Huamn();
Human.HairState.cut(human1);
}
}
The statement
Human.HairState.cut(human1);
is invalid...
I intend to call the public cut() function, which belongs to hairTooLong private attribute.
How should I do it?
Since HairState is private to Human, nothing outside the Human class can even know about it.
You can create a method in Human that relays the call to its private mechanism:
public class Human {
. . .
public float cutHair() {
return hairTooLong.cut(this);
}
}
and then call that from main():
System.out.println(human1.cutHair());
Two other solutions to previous comment:
You can implement a getter which returns the hairTooLong attribute.
You can invoke the the cut() method through the reflection API (but you don't want to go there if you are beginner).
Would suggest either the solution in the previous comment, or the first option presented here.
If you are curious, you can have a look to the reflection API and an example here: How do I invoke a Java method when given the method name as a string?
In java there are four access levels, default, private, public and protected. Visibility of private is only limited to a certain one class only (even subclass cannot access). You cannot call private members in any other class. Here is a basic details of java access levels.
Access Levels
Modifier Class Package Subclass World
public Y Y Y Y
protected Y Y Y N
no modifier Y Y N N
private Y N N N
For more details check Oracle docs

Categories

Resources