I wrote the getPlugin() method to be able to get the main class from another class.
public class Main extends JavaPlugin {
public Main getPlugin() {
return this;
}
}
But when I try to call it...
public class Arena {
private Main plugin = Main.getPlugin();
}
...Eclipse gives me the following error:
Cannot make a static reference to the non-static method getPlugin() from the type Main
I have used static, but static gives me issue's in a lot of different places, and I've seen that static is usually a bad way of doing stuff. Causes memory leaks and stuff.
I have tried using getters and setters, but those need to be static too?
The code I've been using is very messy and I'd like to find a cleaner way of accessing another class.
If you want to avoid using static methods, you need to pass variables as a parameter to the constructor of objects. In your example, it would work like this:
public class Arena {
private final Main plugin;
public Arena(Plugin plugin) {
this.plugin = plugin;
}
}
And then you can create an Arena from your main plugin class, and pass in this as a parameter:
public class Main extends JavaPlugin {
#Override
public void onEnable() {
Arena arena = new Arena(this);
}
}
This problem occurs because there already is a getPlugin() method in the JavaPlugin superclass, so when you do Main.getPlugin() you are trying to call the non-static one.
Also, your own method is non-static.
Here is how I do.
You have to use a different name and make it static. Also, you should initialize its value on onEnable().
public final class Example extends JavaPlugin {
private static Plugin main;
public static Plugin getMain() {
return main;
}
#Override
public void onEnable() {
main = this;
}
}
Related
Is it possible to create object of class in which main method resides.I have been searching for this answer but I have been told that it depends on compiler some compiler will allow while others will not.Is that true?
Yes? The main method is just an entry point. The class is like any other, except it has an additional public static method. The main method is static and therefore not part of the instance of the object, but you shouldn't be using the main method anyway except for starting the program.
public class Scratchpad {
public static void main(String[] args) {
Scratchpad scratchpad = new Scratchpad();
scratchpad.someMethod();
}
public Scratchpad() {
}
private void someMethod() {
System.out.println("Non-static method prints");
}
}
Yes, you can create object for the class which has main method. There is no difference in this class and a class which don't have main method with respect to creating objects and using.
How can static fields of some superclass be protected from alteration (for example in main method), while keeping this possibility via setters in subclasses. As far as i know, making it private won't make the job, because private static fields are not a part of subclasses. Only thing I can excogitate
is making them protected and include those classes (without main class) in a package.
Is there a simplier solution?
class Main{
public static void main(String[] args){
Foo.precious = "nothingness";
}
}
class Foo{
static String precious = "Precious data";
}
class Bar extends Foo{
Foo.precious = "More precious";
}
And if I add a private modifier to the precious in Foo class, then I will protect it from main(), however lose the ability to change it in subclass as well.
There is no access modifier that makes a member/static/method visible to a subclass but not the package.
This is taken from Oracle Documentation
When a subclass is expected to override its super class' behviour, you have to stick to the OOD rules: You'd better make them variables non-static so that the subclasses can re-define them and override its public getters:
class Foo{
private String precious = "Precious data";
public String getPrecious() { return precious; }
}
class Bar extends Foo{
private String precious = "more precious";
#Override
public String getPrecious() { return precious; }
}
class Main{
public static void main(String[] args){
Foo.precious = "nothingness"; // Compilation error: field precious is not visible.
Foo.setPrecious("x"); // Compilation error: No such public method.
}
}
I have a class with a method that takes a single parameter. This parameter is a nested class inside the mocked class, but it is private (And static but I don't think that makes much of a difference to this). How do I go about mocking this method?
Example:
public class myClass {
public anotherObject;
public myClass(AnotherObject anotherObject) {
this.anotherObject = anotherObject;
}
public void exec() {
//Some instructions ...
//This second method is inside another completely seperate class.
anotherObject.secondMethod(new NestedClass());
}
private static class NestedClass {
public NestedClass() {
//Constructor
}
//Variables and methods, you get the picture
}
}
In the above example secondMethod(...) is the method that I want to mock.
All attempts to find other examples of this problem just return results relating to mocking a single private nested class, or mocking static classes, which aren't completely relevant to this and don't seem to provide any work around that I can figure out.
EDIT:
I'm looking for some sort of solution that looks like this:
#Test
public void testExec() {
AnotherObject anotherObject = mock(AnotherObject.class);
when(anotherObject.secondMethod(any(NestedClass.class))).thenReturn(0);
MyClass testThisClass = new MyClass(anotherObject);
}
Notes: I'm not allowed to make modifications to the code I'm afraid, I am only allowed to create these tests to make sure the current implementation works later down the line when modification are made to it.
If I am understanding the requirement correctly, add one method say executeSecondMethod(). Call this method in your main method class.
public class myClass {
public void exec() {
//Some instructions ...
secondMethod(new NestedClass());
}
public void secondMethod(NestedClass example) {
//Some instructions that I want to just mock out...
}
private static class NestedClass {
//Variables and methods, you get the picture
}
public static executeSecondMethod(){
secondMethod(new NestedClass()); // pass the nested class object here
}
}
public class mainClass{
public static void main(){
executeSecondMethod();
}
}
I have two .java files in the same package. I am planning on making the first .java file the underlying code and the second .java file the GUI swing interface.
My problem I encountered was when working on the GUI part of the project, I needed to access several methods from the .java file with the code. My .java file with the code is a like this:
package same;
public class HFSim extends ApplicationTemplate
{
private static class AppFrame extends ApplicationTemplate.AppFrame
{
public myMethodIWanttoUse()
{
//code
}
And in my GUI .java:
package same;
public class GUI extends JFrame
{
public GUI()
{
public void actionPerformed(ActionEvent e)
{
//this is where I want to use the method from above
Is there a way to get that method to be used in the GUI portion? Or is there a better way to approach this problem? thanks in advance.
You have multiple solutions to your problem. The first question you should answer is how these methods you need to call qualify themselves.
Are they utility methods? (They don't require an instance of an object to work on)
Are they attached to a single instance of an object?
Do you need to call methods of a specific object more than just methods?
You can either:
Declare them static and call them, eg HFSim.AppFrame.myMethoIWanttoUse();
Declare a static instance of the object containing them, eg
public class HFSim extends ApplicationTemplate {
public static final AppFrame appFrame = new AppFrame();
...
}
public class GUI extends JFrame {
public GUI() {
public void actionPerformed(ActionEvent e) {
HFSim.appFrame.myMethodIWanttoUse();
}
}
}
Pass the instance of the object to the other one:
public class GUI extends JFrame {
private final HFSim.AppFrame appFrame;
public GUI(HFSim.AppFrame appFrame) { this.appFrame = appFrame; }
public void actionPerformed(ActionEvent e) {
appFrame.myMethodIWanttoUse();
}
}
Make methodIWantToUse() static by replacing
public myMethodIWanttoUse()
with
public static myMethodIWanttoUse()
Secondly, make AppFrame marked as public instead of private.
Then just call you method like this HFSim.AppFrame.myMethodIWantToUse().
Edit:
Alternatively, you don't have to make your method static. Just add this in your GUI code:
HFSim.AppFrame frame = new HFSim.AppFrame();
frame.myMethodIWantToUse();
Still, no matter what, you have to make AppFrame be public.
I need to extend the functionality of my main class, by overriding some of its methods. I was expecting that the class extending the main class would be able to be run. However, Eclipse doesn't recognize MyLauncher as a runnable class. In the following code, I have a setup() method that is overridden by the subclass. What I want is a way to run the main(..) from the super class but also the setup from the subclass.
// Launcher.java
public class Launcher {
Launcher instance;
public static void main (args[]) {
instance = new Launcher(); // This is likely the problem
instance.setup();
}
public void setup() {
System.out.println("Default agent setup.");
}
}
// MyLauncher.java
public class MyLauncher extends Launcher {
public void setup() {
System.out.println("New agent setup!");
}
}
I accept alternatives to this. I can't add a main method to the subclass, though. The Launcher class is inside an API i'm making, so it can't refer to the class MyLauncher that is using the API.
edit: I think this is to specific to my problem. I decided to search for a new approach. Since I'm working with JDT, I'm going to parse the Launcher and inject the class.
Static methods are not inherited, they're always bound to the class that defines them, and need to be called explicitely.
In you case, the MyLauncher needs a main() method too, and could then delegate to the main() method of Launcher:
public class MyLauncher extends Launcher {
public static void main (String[] args) {
Launcher.main(args);
}
protected void setup() {
System.out.println("New agent setup!");
}
}
Protected methods can not be called from outside. So the MyLauncher.setup() do not override Launcher.setup() and instance.setup(); calls the public method from Class Launcher.
There can only be one main method in your project, that is one entry point to the program. So let's assume you're going to be keeping the main method in the Launcher class.
Your main method signature should be:
public static void main (String args[])
And unless you want the setup() method from the launcher to be called you'd want to do:
instance = new MyLauncher();
That would call the setup() method from MyLauncher.
If you want to call setup() from the Launcher class you need to instantiate the launcher class:
instance = new Launcher();
If you want to be able to run MyLauncher.setup(), the variable must be a MyLauncher. You are initializing and storing a Launcher in the main() function.
If the two classes are in the same package, or Launcher.java imports the MyLauncher class, then the main() function in Launcher should be able to be:
public class Launcher {
Launcher instance;
public static void main(String[] args) {
instance = new MyLauncher();
if(instance instanceof MyLauncher) {
((MyLauncher) instance).setup();
} else
{
instance.setup();
}
}
}
As you say, the fact that you create an instance of Launcher directly in main means that no inheritance is available. Even if you could start MyLauncher easily from Eclipse, within the main method you wouldn't know which type had actually been used to start it. I can't see any easy solution that doesn't involve either creating a main method in each class or providing the class name as a command-line argument. I would probably separate the "running" from anything else:
public class Launcher {
public static void launch(LaunchConfiguration configuration) {
configuration.setup();
...
}
}
public class LaunchConfiguration {
public static void main(String[] args) {
Launcher.launch(new LaunchConfiguration());
}
public void setup() {
}
}
public class MyLaunchConfiguration {
public static void main(String[] args) {
Launcher.launch(new MyLaunchConfiguration());
}
#Override
public void setup() {
}
}