For some reason after I had added and removed a static vairable from my code, eclipse started giving me errors on all functions that I call, saying that these functions must be static. However, if I let the program run with these errors, the program runs just as I intended it to do. My Code:
package main;
public class Main implements Runnable {
public void start() {
Thread thread = new Thread(this);
thread.start();
System.out.println("Running...");
Ball.test(); <--- Giving me an error
}
public void run() {
}
public void stop() {
System.out.println("Exiting...");
}
}
and when I create a method in ball called test it gives me:
public static void test() {
// TODO Auto-generated method stub
}
Well yes - you're calling the method as if it were a static method:
Ball.test()
If you want to call an instance method, you need to call it on an instance, e.g.
Ball ball = new Ball();
ball.test();
It's important to understand the difference between static members and instance members. Have you read the appropriate chapter of the Java tutorial? Do you have a good Java book which would help you? (Stack Overflow is great for specific questions, but not good for learning a language from scratch. Explaining language concepts well takes a lot of space and time.)
Related
I'm working on a code in a wicket project, where the original devs used the onModelChanged() method quite a lot in Ajax request handling methods. I, for one, however am not a strong believer of this implementation.
In fact, I can't think of any examples, where calling the target.add(...) is inferior to calling the onModelChanged method.
Am I missing some key concepts here?
Example:
public MyComponent extends Panel {
public MyComponent(String id, Component... componentsToRefresh) {
add(new AjaxLink<Void>("someId") {
#Override
public void onClick(AjaxRequestTarget target) {
// some logic with model change
for(Component c: componentsToRefresh) {
c.modelChanged();
}
target.add(componentsToRefresh);
}
};
}
}
Now, there are a couple of things I don't agree with, the very first is the componentsToRefresh parameter, the second is (as the question suggests), the fact that we called c.modelChanged() on all components in that array. My guess would be that it is completely un necessary and instead of a parameter in the constructor, one should just write an empty function in MyComponent and override it, and put the necessary components in there when needed.
I would suggest to use Wicket Event system instead. That is, whenever the AjaxLink is clicked you will broadcast an event:
send(getPage(), Broadcast.BREATH, new MyEventPayload(target));
This will broadcast the event to the current Page and all its components.
Then in any of your components you can listen for events:
#Override
public void onEvent(IEvent event) {
Object payload = event.getPayload();
if (payload instanceof MyEventPayload) {
((MyEventPayload) payload).getTarget().add(this); // or any of my sub-components
event.stop(); // optionally you can stop the broadcasting
}
}
This way you do not couple unrelated components in your application.
See Wicket Guide for more information.
My goal is to write a class and have a function in it that contains code to run (in a run() function for example) in a background thread. Here are some requirements of my class (and related classes):
Ensure that when I write the run() function, the code is guaranteed to run in a background thread without the programmer needing to know anything about threading and without having to remember to call any other code in that run() function related to the threading.
Have a completion function function that is set elsewhere that is called when the background thread is finished its processing without the programmer having to write code in this run() function to make the call.
Pretty much let someone derive a class from some base class and then write their background code in it in a run() function without writing anything else related to managing the background thread, completion function, etc.
Here's the code I might write in C#, in two DIFFERENT files:
class MyBase
{
public Action completionFunction = NULL;
public void begin()
{
RunInOtherThread( run ); // This function call is just pseudo-code for running that run() function in a background thread.
if( completionFunction != Null )
completionFunction();
}
virtual protected void run() = 0 // so this class cannot be instantiated
{
}
};
And in the other file:
class MySpecificClass : MyBase
{
override void run()
{
// Do important stuff here!
}
};
I do not know how to meet my requirements in Swift. They left out the "protected" level of protection for reasons that do not make sense to me (like thinking that I could not just fire a programmer that screwed up the code by exposing a base class protected function through a public function).
I am not familiar enough with some of the features of Swift to get these results. I do not need to have the classes work like the C# code even though it is a pretty good solution for me and my C# programmers.
How can I meet my requirements Swift?
BTW, I have seen Q&A about this with no reasonable way to fake the protected access level. I don't need to fake it, I just need another way to achieve the goal of hiding code in a derived class from all the world except for the base class, or something like that.
I'd be tempted to use protocols for this, rather than sub-classing. For example:
public protocol MyBase {
// *** This requires any object that conforms to the protocol
// *** to provide these, without specifying what they do
var completionFunction: (() -> ())? {get set}
func run()
}
public extension MyBase {
// *** This extension provides all objects that conform to the
// *** protocol with this function
func begin() {
RunInOtherThread( self.run ) // This function call is just pseudo-code for running that run() function in a background thread.
if let c = self.completionFunction {
c()
}
}
}
public class MySpecificClass: MyBase {
// *** Now, rather than subclassing, we simply conform to the protocol
public var completionFunction: (() -> ())? = nil
public func run() {
// *** No need to `override` - but *must* be supplied
// Do important stuff here!
}
}
I have several UI-Components which have listeners. All these listeners invoke method dialogChanged(). My goal is to make some long processing in this method and don't let the UI freeze. According to Lars Vogel it is possible to do this with help of UISynchronize being injected during runtime. But it fails for me, field of this type is not being injected and i get a NullPointerException. Here's relevant part of my code:
#Inject UISynchronize sync;
Job job = new Job("My Job") {
#Override
protected IStatus run(IProgressMonitor arg0)
{
sync.asyncExec(new Runnable()
{
#Override
public void run()
{
updateStatus("Checking connection...");
if (bisInstallDirSelected)
bisSettingsChanged();
else
jarSettingsChanged();
}
});
return Status.OK_STATUS;
}
};
protected void dialogChanged()
{
job.schedule();
}
The methods updateStatus(String s), bisSettingsChanged() and jarSettingsChanged() interact with UI, to be presice, they use method setErrorMessage(String newMessage) of superclass org.eclipse.jface.wizard.WizardPage
I'd appreciate if somebody could tell me what I am doing wrong or suggest a better way to handle this problem.
You can only use #Inject in classes that the e4 application model creates (such as the class for a Part or a Command Handler).
You can also use ContextInjectionFactory to do injection on your own classes.
For classes where injection has not been done you can use the 'traditional' way of running code in the UI thread:
Display.getDefault().asyncExec(runnable);
Is it possible to do Inter Type Declarations with AspectJ on Compiled Class Files at Load Time Weaving?
As an example: I compile some Groovy code and want to add fields or methods with IDT.
Update:
Oh my goodness, you do not need reflection to access members or execute methods. Eclipse shows errors in the editor, but you may just ignore them, the code compiles and runs fine anyway. So the aspect is really much more strightforward and simple:
public aspect LTWAspect {
public static String Application.staticField = "value of static field";
public String Application.normalField = "value of normal field";
public void Application.myMethod() {
System.out.println(normalField);
}
void around() : execution(void Application.main(..)) {
System.out.println("around before");
proceed();
System.out.println("around after");
System.out.println(Application.staticField);
new Application().myMethod();
}
}
Original answer:
Yes, but you have a hen-and-egg problem there, i.e. you cannot just reference the newly introduced fields from your LTW aspect code without reflection. (The last sentence is not true, see update above.) Plus, in order to make your LTW aspect compile, you need the classes to be woven on the project's build path so as to be able to reference them. Example:
Java project
public class Application {
public static void main(String[] args) {
System.out.println("main");
}
}
AspectJ project
import org.aspectj.lang.SoftException;
public aspect LTWAspect {
public static String Application.staticField = "value of static field";
public String Application.normalField = "value of normal field";
public void Application.myMethod() {
try {
System.out.println(Application.class.getDeclaredField("normalField").get(this));
} catch (Exception e) {
throw new SoftException(e);
}
}
void around() : execution(void Application.main(..)) {
System.out.println("around before");
proceed();
System.out.println("around after");
try {
System.out.println(Application.class.getDeclaredField("staticField").get(null));
Application.class.getDeclaredMethod("myMethod", null).invoke(new Application());
} catch (Exception e) {
throw new SoftException(e);
}
}
}
So, e.g. in Eclipse you need to put the Java project on the AspectJ project's build path under "Projects" because only then it can see Java class Application on which you want to declare members. After compilation you just start the Java project and do LTW on the aspect project (don't forget an aop-ajc.xml referencing LTWAspect).
In my example above I declare a static member, a non-static ("normal") member and a non-static method. My advice prints the static member and calls the non-static method, both via reflection. The non-static method then prints the non-static member, again via reflection. This is not nice, but it works and proves the ITD in combination with LTW is possible. There might be a more elegant way, but if so I am unaware of it. (Update: There is a more elegant way: Just ignore the errors marked by Eclipse IDE, see above.)
Program output
around before
main
around after
value of static field
value of normal field
I'm messing around with Eclipse(and java in general) for the first time in about a year. among the things I have forgotten is the following:
I have a function (void callvote() that I am hoping will be activated by my main function (that is, automatically, relatively early in the program). I currently have it within the same class (body) as the main function itself.
I try to call it withcallvote(); and get an error, "- Cannot make a static reference to the non-static method callvote() from the type body"
my function callvote is, at the moment, in the space below main and simply says
public void callvote()
{
}
am i committing a horrible sin by putting more functions in the same class as main?
is this a relatively easy fix that I missed somehow?
What does this error mean?
Have I woken Azatoth with this code?
Thanks in advance,
Tormos
Without the static modifier callvote is implicitly an instance method - you need an instance of a class to call it.
You could mark it as static also:
public static void callvote() ...
Or create an instance of the declaring class:
MyClass instance = new MyClass();
instance.callvote();
main() is a static method, meaning you can call it directly from a class whereas non-static members can only be called from an object. In order for you to call the callvote() method you need to first instantiate an object of your class:
public static void main(String [ ] args) {
MyClass myObject = new MyClass();
myObject.callvote();
}
Another way to avoid the error is to make you callvote() method static as well, but it's usually not what you want to do (but it depends on the nature of your class and method).
This post describes some of the dangers with the overuse of static methods: Class with single method -- best approach?
Try this:
public class Main {
public static void main(String[] args) {
new Main().callvote()
}
}
the main() entry point of your java program is static. You cannot call a non static method from a static one.
So you have to instanciate your Class first and call the method after.