Static members of inner, anonymous, method local classes - java

Several Java textbooks state that member inner classes cannot have static members except for static final fields. However, I have been able to create such classes that compile and run successfully. For example:
class Swimmer{
class SwimmerAssistant{
static int count = 0;
SwimmerAssistant(){
count++;
}
public static void assist(){
System.out.println("I am helping the Swimmer");
}
}
public static void main(String[] args) {
SwimmerAssistant.assist(); // prints "I am helping the Swimmer"
System.out.println(SwimmerAssistant.count); // prints 0
Swimmer swimmer1 = new Swimmer();
Swimmer.SwimmerAssistant swimmerAssistant = swimmer1.new SwimmerAssistant();
Swimmer swimmer2 = new Swimmer();
Swimmer.SwimmerAssistant swimmerAssistant2 = swimmer2.new SwimmerAssistant();
System.out.println(SwimmerAssistant.count); // prints 2
}}
How is this possible?
Many thanks.

Related

Method and Variable Scope Issue in Java

I need help I cannot figure out how to fix the scope of my variables. I want this to be an example for my notes but have been on it for almost 2 hours.
public class methodPractice{
String streetName;
int streetNum;
public static void streetName()
{
String streetName = "Pope Ave.";
}
public static void streetNum()
{
int streetNum = 11825;
}
public static void main(String[] args)
{
streetName();
streetNum();
System.out.println("This is your home adress: " + streetNum +
streetName);
}
}
Thank you for your help.
You are shadowing the fields. Use this to make sure you get the fields, or a compile error.
public static void streetName()
{
this.streetName = "Pope Ave.";
}
public static void streetNum()
{
this.streetNum = 11825;
}
Here is your main method, with line numbers added:
1. public static void main(String[] args) {
2. streetName();
3. streetNum();
4. System.out.println("This is your home adress: " + streetNum + streetName);
5. }
A few points...
When line 2 runs, "streetName()" calls the static method below. The static keyword says you are free to call the method by itself – that is, you don't need an object; you don't need to call new methodPractice() first.
public static void streetName() {
String streetName = "Pope Ave.";
}
When line 3 runs, it's the same thing: "streetNum()" calls a different static method – again, totally fine to call this by itself.
public static void streetNum() {
int streetNum = 11825;
}
Line 4 is different, there are a few things going on. Your expectation is that "streetNum" finds the int that you declared on the class, but it doesn't work. Why? Because you defined that member with "int streetNum" – without "static". So what? Without being declared static, it means "streetNum" belongs to an object instance. What does that look like? Here's an example showing object creation, followed by setting the object member "streetNum" to 1.
methodPractice object = new methodPractice();
object.streetNum = 1;
You could work around this by declaring both of the non-static members to be static (static String streetName, and static int streetNum). Or you could leave them as is, and interact with them through an object instance (after doing new ..).

How to add to array in main?

I have created an array which I wanted to control from main. My code runs, but I don't know how to add integers to the array from the main class. Also as each ConcreteSubject has its own storage array, how would i change this to store them all in the same array?
public class ConcreteSubject extends AbstractSpy
{
private AbstractSpy[] spies = new AbstractSpy[10];
private int i = 0;
public void addSpy(AbstractSpy s) {
if (i < spies.length) {
spies[i] = s;
System.out.println("spy added at index " + i);
i++;
}
}
}
public class TestClass
{
public static void main(String[] args) {
ConcreteSubject cs = new ConcreteSubject();
AbstractSpy spies = new AbstractSpy() {
#Override
public void addSpy(AbstractSpy spies) {
}
};
cs.addSpy(cs);
spies.addSpy(spies);
}
}
It seems like your program logic is a little borked. This bit in particular doesn't make much sense:
***AbstractSpy spies = new AbstractSpy() {
#Override
public void addSpy(AbstractSpy spies) {
}
};
cs.addSpy(cs);
***spies.addSpy(spies);
What you're doing is creating TWO AbstractSpy instances, one named cs and one named spies. On that last line you're adding spies to itself! That doesn't help you at all.
Note that AbstractSpy is the most granular unit in your setup - it shouldn't have an addSpy() method and its own internal array, it should be the thing that's added to something else's array!
Here's the same code, but cleaned up a bit:
public abstract class AbstractSpy { }
public class ConcreteSpy extends AbstractSpy { }
public class ConcreteSubject {
private AbstractSpy[] spies = new AbstractSpy[10];
private int i = 0;
public void addSpy(AbstractSpy spy) {
if (i < spies.length)
{
spies[i] = spy;
System.out.println("spy added at index " + i);
i++;
}
}
}
public class TestClass {
public static void main(String[] args) {
ConcreteSubject cs = new ConcreteSubject();
AbstractSpy spy = new ConcreteSpy();
cs.addSpy(spy);
}
}
The big difference here is that ConcreteSpy is an implementation of AbstractSpy that you can add to your ConcreteSubject's array of spies. I think you might have been confused by Java's insistence that you can't create an instance of an abstract class on its own unless you supply an anonymous class that inherits from the abstract class.

Error: Main method not found in class MovieDatabase [duplicate]

This question already has answers here:
Error: Main method not found in class Calculate, please define the main method as: public static void main(String[] args) [duplicate]
(5 answers)
Closed 8 years ago.
Error: Main method not found in class MovieDatabase, please define the main method as: public static void main(String[] args) or a JavaFX application class must extend javafx.application.Application
import java.io.FileInputStream;
import java.util.Scanner;
import java.util.Arrays;
public class MovieDatabase {
private int[] analysis;
//creating the contructor
public MovieDatabase(String file){
analysis = new int[2015];
this.load(file);
}
//uses the load(String file) method from downstairs to do all of the work
public void load(String file){
Scanner theScanner = null;
try{
//inputing the into the scanner
theScanner = new Scanner(new FileInputStream(file));
}
catch(Exception ex){
ex.printStackTrace();
}
// as long as the scanner has another line
while(theScanner.hasNextLine())
{
String Line = theScanner.nextLine();
//make an array called split and allocated different elements based on a seperation of ##
String split[] = Line.split("##");
int year = Integer.valueOf(split[1]);
analysis[year] ++;
}
}
//print out the array in the synchronous format
public void print(){
System.out.printf("%1$-30s %2$10s %3$10s %4$10s ", "Year", "Occurances", "", "");
//go through the array
for (int i =0;i < analysis.length ;i++ ) {
if(analysis[i] >0){
for (int j =i;j < analysis.length ;i++ ){
System.out.printf("%1$-30s %2$10s %3$10s %4$10s ", j, analysis[j], "", "");
}
}
}
}
}
How do I fix this error message?
Ive read other similar questions but just say to make the classes public. Mine are public.
main() method in Java is an standard method which is used by JVM to start execution of any Java program. main method is referred as entry point of Java application which is true in case of core java application
You have missed it. Add following main() method
public static void main(String[] args) {
MovieDatabase db = new MovieDatabase("file/path/goes/here");
db.print();
}
In the Java programming language, every application must contain a
main method whose signature is:
public static void main(String[] args)
As the error suggests, if its non FX project, just define something like:
public static void main(String args[]) {
...
}
Or else change you class definition so it extends Application, something like:
public class MovieDatabase extends Application
To invoke any application JVM need main() method, and which should have following access specifiers and modifiers,
public static void main(String args[])
public - It should be accessible to all
static - JVM not able to create instance of your class so method should be static
void - method not returning anything
For each java application main method is entry point, so your application should have atleast one main method to start execution of application.
It's because you have forgot to add the main method. The error clearly says:
please define the main method as: public static void main(String[]
args)
So add the main:
public static void main(String[] args) {
MovieDatabase m = new MovieDatabase("Your File Path");
m.print();
}

Java - use class defned in Main in another class

I'm new to Java and we have to make this little project. So i have 3+ classes.
MY code is in pastebin
http://pastebin.com/GEq9DLiP
etc. etc.
Problem is, that in 3rd class it sais
"kangelane cannot be resolved"
but kangelane is already "defined" in Main.java and they are in same package.
Oh and Eclipse also wants to add "open bracet" after
int sook = 4; or
int dam;
and also "clode bracket" to the end
even though all open brackets are closed and vice versa
I have Getters and Setters in "Voitleja.java", so that works.
It also worked, when i only had 2 classes not 3 (Voitlus was in Main)
The problem is that main is a static class, if you want to use a variable in both main and in an oter class, you have to defined it as a static variable, for your example you should do :
public class Main {
static Voitleja kangelane;
public static void main(String[] args) {
String nimi = JOptionPane.showInputDialog("Sisestage võitleja nimi");
kangelane = new Voitleja(nimi, 55, 12);
}
}
Then in your other class (assuming the import are correct)
public class Voitlus{
Random generator = new Random();
int dam;
int sook = 4;
while (true) {
Main.kangelane.setElud(kangelane.getElud() + 7);
}
}
public static void main(String[] args) {
String nimi = JOptionPane.showInputDialog("Sisestage võitleja nimi");
Voitleja kangelane = new Voitleja(nimi, 55, 12);
}
(later)
while (true) {
kangelane.setElud(kangelane.getElud() + 7);
}
The variables are in a different scope. You have to declare kangelane right after your public class declaration so both methods can "see" it.

how to stop getting the same number when generating 2 numbers from a different class

When I run this code i get 2 numbers (which is good) but the numbers generated are the same (which is bad) and I dont want the numbers to be the same. I've done this as an experiment for a rpg I was going to make so I thought it would be beter if each weapon had a different class.
The main class:
package battlesimMK2;
public class Main {
public static void main(String Arg[]) {
String WeponEquiped = "BasicAxe";
System.out.print(BasicAxe.Str);
System.out.print(BasicAxe.Str);
}
}
The basic axe class:
package battlesimMK2;
import java.util.Random;
public class BasicAxe {
static Random rnd = new Random();
static int Str = rnd.nextInt(4)+5;
}
This line:
static int Str = rnd.nextInt(4)+5;
declares a static variable and initializes it once. If you want the code to run each to you access Str, you should make it a method:
public static int getStrength() {
return rnd.nextInt(4)+5;
}
Then call it with this code in Main.main:
System.out.print(BasicAxe.getStrength());
System.out.print(BasicAxe.getStrength());
An alternative which would probably be more object-oriented would be to make the strength an instance field, so that each axe created had a possibly-different (but persistent) strength:
public class BasicAxe {
private static final Random rnd = new Random();
private final int strength;
public BasicAxe() {
strength = rnd.nextInt(4)+5;
}
public int getStrength() {
return strength;
}
}
Then in Main.main:
BasicAxe axe1 = new BasicAxe();
BasicAxe axe2 = new BasicAxe();
System.out.println(axe1.getStrength());
System.out.println(axe2.getStrength());
System.out.println(axe1.getStrength());
Here, the first and third lines of output will be the same - but the second will (probably) be different.
You're generating a single random number and printing it twice. Try something like this instead:
package battlesimMK2;
public class Main {
public static void main(String Arg[]) {
String WeponEquiped = "BasicAxe";
System.out.print(BasicAxe.Str());
System.out.print(BasicAxe.Str());
}
}
package battlesimMK2;
import java.util.Random;
public class BasicAxe {
static Random rnd = new Random();
static int Str() { return rnd.nextInt(4)+5; }
}
This because this line
static int Str = rnd.nextInt(4)+5;
runs just one time in whole the lifecycle of your application. It's static value, you should use static method instead.
Because you define the Str variable as static, only a single copy of that variable is shared between all your BasicAxe classes.
The way to get a different answer each time you ask for the int value is, to use the example posted by the previous poster,
String WeponEquiped = "BasicAxe";
System.out.print(BasicAxe.getStrength());
System.out.print(BasicAxe.getStrength());
But, if you want to create an actual instance of the class BasicAxe, which keeps it's value so that each time you ask for the strength you get the same value, you'll need something different.

Categories