I have a static nested class StatClass, the file name is Example.java
class OuterClass
{
public static class StatClass
{
System.out.println("Hello"); // This line doesn't work
void pow()
{ System.out.println("Hello W");}
}
}
public class Example
{
public static void main(String[] args)
{
OuterClass.StatClass statInner1 = new OuterClass.StatClass();
statInner1.pow();
}
}
The first println statement doesn't work in the static nested class i.e if its removed then the program compiles, although the println statement works when inside the pow() method, couldn't understand this
Like in a normal class, you can't just put statements inside a class. You could put it in an initializer-block like this:
{
System.out.println("Hello");
}
Or in a constructor, or a method. Whatever you want.
I am just uniting the two answers so far:
one option is a static block
class OuterClass
{
public static class StatClass
{
static {
System.out.println("Hello"); // This line doesn't work
}
void pow()
{ System.out.println("Hello W");}
}
}
public class Example
{
public static void main(String[] args)
{
OuterClass.StatClass statInner1 = new OuterClass.StatClass();
statInner1.pow();
OuterClass.StatClass statInner2 = new OuterClass.StatClass();
statInner2.pow();
}
}
The main difference is how the block is executed by the JVM. In the first case it is executed once during the class initialization. Then the output will be :
Hello
Hello W
Hello W
Another option is initializer block in which case the code will be executed on each instantiation of the class.
class OuterClass
{
public static class StatClass
{
{
System.out.println("Hello"); // This line doesn't work
}
void pow()
{ System.out.println("Hello W");}
}
}
public class Example
{
public static void main(String[] args)
{
OuterClass.StatClass statInner1 = new OuterClass.StatClass();
statInner1.pow();
OuterClass.StatClass statInner2 = new OuterClass.StatClass();
statInner2.pow();
}
}
Then the output will be:
Hello Hello W Hello Hello W
Following statement is outside method that wont work
System.out.println("Hello"); // This line doesn't work
You have to wrap these statements inside static block as follows
static{
System.out.println("Hello"); // This line will work
}
this block will execute when JVM create static instances.
System.out.println("Hello");
This does not work because,the control never goes to the line. Unless you define this inside a function and use the object you created to call it OR use the static block which does not require an object to call it OR an initializer block, it will not work. I hope that helps
Related
The following sample program prints Hello. the method exampleMethod(Runnable toRun) has a Runnable type parameter. The function pointer MyTest::sayHello does not have a run method. How is it got executed?
public class MyTest {
// Method that takes a "method" as argument
static void exampleMethod(Runnable toRun) {
toRun.run();
}
// Method to pass
static void sayHello() {
System.out.println("Hello");
}
public static void main(String[] args) throws Exception {
exampleMethod(MyTest::sayHello); // prints "Hello"
}
}
The code inside the main method is same as:
Runnable runnable = () -> {
MyTest.sayHello();
};
exampleMethod(runnable);
I have two classes and one interface.
Interface:
public interface MyBirthdayEvent {
void itsMyBirthday();
}
First class:
public class MyBirthdayButton
{
public void addOnClickedListener(MyBirthdayEvent mbe){}
}
Second class:
public class MyBirthday {
private MyBirthdayButton myBirthdayButton = new MyBirthdayButton();
MyBirthday() {
myBirthdayButton.addOnClickedListener(new MyBirthdayEvent() {
public void itsMyBirthday() {
System.out.println("Happy Birthday");
}
});
}
}
Then in main, I have this:
public class TestThisStuff {
public static void main(String[] args) {
MyBirthday myBirthday = new MyBirthday();
}
}
As can be seen from the code, I am using an anonymous class in the MyBirthday constructor. In doing so, I am trying to get the string "Happy Birthday" to print to the console.
My problem is, when I call the MyBirthday constructor in main by making a new myBirthday object, I am not seeing the string "Happy Birthday" print to the console. Shouldn't it print to the console? If not, what I am doing wrong?
What you can do is this:
public interface MyBirthdayEvent {
void itsMyBirthday();
default void invoke() {
itsMyBirthday();
}
}
...
public class MyBirthdayButton
{
public void addOnClickedListener(MyBirthdayEvent mbe){
mbe.invoke();
}
}
...
Also, it will work without it, but use a lambda rather than an anonymous inner class. This looks much better.
MyBirthday() {
myBirthdayButton.addOnClickedListener(() ->
System.out.println("Happy Birthday"));
}
you can move System.out.println("some words")statement to your MyBirthdayEventconstructor
it didn't show in your console because you haven't invoke the method
I want to execute one function before main function in C and JAVA language.
I know one way that is, by using #pragma directive in C language. Is there any other way to do that in both languages?
I can think of two simple(-ish) ways to do it in Java:
Method #1 - static initializers
For example:
public class Test {
static {
System.err.println("Static initializer first");
}
public static void main(String[] args) {
System.err.println("In main");
}
}
Method #2 - A proxy main.
public class ProxyMain {
public static void main(String[] args) {
String classname = args[0];
// Do some other stuff.
// Load the class
// Reflectively find the 'public static void main(String[])' method
// Reflectively invoke it with the rest of the args.
}
}
You then launch this as:
java <jvm-options> ... ProxyMain <real-Main> arg ...
There is also a 3rd method, but it requires some "extreme measures". Basically you have to create your own JVM launcher that uses a different scheme for starting the application. Have this do the extra stuff before loading the entry point class and calling its main method. (Or do something different entirely.)
You could even replace the default classloader; e.g. How to change default class loader in Java?
in java you can use static block
public class JavaApplication2 {
static {
System.out.println("in static ");
}
public static void main(String[] args) {
System.out.println("in main ");
}
}
As an extension to the C standard gcc provides the function attribute constructor which allows functions to be called before main().
For details please see here (scroll down). Also this SO question and its answers help on this.
Try combining a static block and a static method containing what you want executed before your main method.
package test;
public class Main {
static {
beforeMain();
}
public static void main(String[] args) {
System.out.println("after");
}
private static void beforeMain() {
System.out.println("before");
}
}
Output:
before
after
It could be the first thing you call from your main function. That way it will run before your "real" main function.
Use that method(what you want to run before main method) as your main method.
Then it is so simple
Or use static block before main()
In java, execution of any other method is possible before main() method execution. We need a static initializer block for that. It starts with a static keyword.
Like:
static {
// statements
}
Now try to understand with actual code implementation.
public class BefourMain {
static int sum;
static {
sum = add(4,5,6);
System.out.println("Calling add() method: " + sum);
System.out.println("\ncalling main");
main(null);
System.out.println("Main end\n");
System.out.println("Now JVM calling main()\n");
}
public static void main(String[] args) {
int sum = add(1,2,3);
System.out.println(sum);
}
static int add(int a, int b, int c) {
return a + b + c;
}
}
Now try to understand with actual code implementation.
When we start executing this code the static initializer block will start execution first, in the static initializer block we are calling the add() method and storing the value in the static variable, and printing it. Next, we are calling the main() method, which will execute. when the static initializer block execution will complete JVM will call the main() method again.
Output
Output of the above code
I'm trying to inline java method using eclipse jdt/ast.
For example, I'd like to make this code
class Hello {
static void hello() {
System.out.println("hello");
}
public static void main(String[] args) {
hello();
System.out.println("z");
hello();
System.out.println("h");
hello();
}
}
into this.
class Hello {
public static void main(String[] args) {
System.out.println("hello");
System.out.println("z");
System.out.println("hello");
System.out.println("h");
System.out.println("hello");
}
}
I could get the body block of hello() method stored in Block bl.
I also have the body block of main() method stored in Block block, and I could delete hello(); ExpressionStatements in the block.
Then, I need to insert the Block bl to where the hello(); is invoked.
I tried
block.statements().add(position, bl.getAST());
and
block.statements().add(position, bl);
where position is the location of hello() method in statements(), but both of them raises an error.
What might be wrong? As Block is Statement, I guess one can insert Block in Block#statements().
ADDED
Based on sevenforce answer, I could get the block inserted, but I have the { and } included.
class Hello {
public static void main(String[] args) {
{
System.out.println("hello");
}
System.out.println("z");
{
System.out.println("hello");
}
System.out.println("h");
{
System.out.println("hello");
}
}
}
Is there any way to remove them?
ADDED2
With this code:
ASTNode singleStmt = (ASTNode) bl.statements().get(0);
block.statements().add(position, ASTNode.copySubtree(bl.getAST(), singleStmt));
It shows only the first statement in hello() method. For example, with
static void hello() {
System.out.println("hello");
System.out.println("hello2");
}
I have only System.out.println("hello"); inlined.
There are several reasons for add throwing an exception.
Normally the specific exception should give you a hint. E.g. the node to be added must be in the same AST.
In your case I'd guess, that you attempt to add the same block object, which is already used in the MethodDeclaration node of hello() and each node is allowed to have just one parent.
A possible solution to that is copying the node:
block.statements().add(position, ASTNode.copySubtree(bl.getAST(), bl));
For extracting single statements the following should work:
ASTNode singleStmt = (ASTNode) bl.statements().get(0);
block.statements().add(position, ASTNode.copySubtree(bl.getAST(), singleStmt));
To add all statements from the block you can just loop over:
for (int i = 0; i < bl.statements().size(); i++) {
ASTNode singleStmt = (ASTNode) bl.statements().get(i);
block.statements().add(position + i,
ASTNode.copySubtree(bl.getAST(), singleStmt));
}
Instead of adding to the block you might think of replacing the method invocation.
final ASTRewrite rewriter = ASTRewrite.create(compilationUnit.getAST());
rewriter.replace(methodInvocationNode, blockNode, null);
So i'm having a bit of a problem trying to compare two strings declared in the Main class. I've messed around with it and i really can't get it to work! The problem is in the if() statement where i compare the variables...
public class Main {
public String oldContent = "";
public String newContent = "";
public static void main(String[] args) throws InterruptedException {
Main downloadPage = new Main();
downloadPage.downloadPage();
oldContent = newContent;
for (;;) {
downloadPage.downloadPage();
if (!oldContent.equals(newContent)) { // Problem
System.out.println("updated!");
break;
}
Thread.currentThread().sleep(3000);
}
}
private void downloadPage() {
// Code to download a page and put the content in newContent.
}
}
the variables are instance members, whereas the for happens in a static method.
try moving the actual function to an instance method (not static), or conversely make the data members static as well.
You may use name of the object you have created (downloadPage ) to access to the parameters:
in the main finction use following instead of parameter names only:
downloadPage.oldContent
downloadPage.newContent
The variables are inside the Main object:
public static void main(String[] args) throws InterruptedException {
Main downloadPage = new Main();
downloadPage.downloadPage(); // Access them like you accessed the method
downloadPage.oldContent = downloadPage.newContent;
for (;;) {
downloadPage.downloadPage();
if (!downloadPage.oldContent.equals(downloadPage.newContent)) {
System.out.println("updated!");
break;
}
Thread.currentThread().sleep(3000);
}
}
Do consider using getters and setters instead of exposing the fields.
See non static/ static variable error