Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #34024 > unrolled thread

Why does Java argue about making a class instance

Started byPopping mad <rainbow@colition.gov>
First post2016-03-26 19:44 +0000
Last post2016-06-29 00:56 -0700
Articles 13 — 7 participants

Back to article view | Back to comp.lang.java.programmer


Contents

  Why does Java argue about making a class instance Popping mad <rainbow@colition.gov> - 2016-03-26 19:44 +0000
    Re: Why does Java argue about making a class instance Joerg Meier <joergmmeier@arcor.de> - 2016-03-26 21:01 +0100
      Re: Why does Java argue about making a class instance Popping mad <rainbow@colition.gov> - 2016-03-28 13:19 +0000
        Re: Why does Java argue about making a class instance Eric Sosman <esosman@comcast-dot-net.invalid> - 2016-03-28 14:59 -0400
    Re: Why does Java argue about making a class instance Eric Sosman <esosman@comcast-dot-net.invalid> - 2016-03-26 16:04 -0400
      Re: Why does Java argue about making a class instance Popping mad <rainbow@colition.gov> - 2016-03-28 13:24 +0000
        Re: Why does Java argue about making a class instance Arne Vajhøj <arne@vajhoej.dk> - 2016-03-28 09:50 -0400
        Re: Why does Java argue about making a class instance Eric Sosman <esosman@comcast-dot-net.invalid> - 2016-03-28 15:04 -0400
          Re: Why does Java argue about making a class instance FredK <fred.l.kleinschmidt@gmail.com> - 2016-03-28 15:17 -0700
            Re: Why does Java argue about making a class instance Eric Sosman <esosman@comcast-dot-net.invalid> - 2016-03-28 18:30 -0400
    Re: Why does Java argue about making a class instance Andreas Leitgeb <avl@logic.at> - 2016-03-26 20:17 +0000
    Re: Why does Java argue about making a class instance Arne Vajhøj <arne@vajhoej.dk> - 2016-03-28 10:10 -0400
    Re: Why does Java argue about making a class instance Roedy Green <inquiry@mindprod.com> - 2016-06-29 00:56 -0700

#34024 — Why does Java argue about making a class instance

FromPopping mad <rainbow@colition.gov>
Date2016-03-26 19:44 +0000
SubjectWhy does Java argue about making a class instance
Message-ID<nd6orl$k7m$1@reader1.panix.com>
When I try to compile this (example from antlr4 FIWIW)

import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.TerminalNode;
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.*;
import java.util.HashSet;

public class Main {
    public static void main(String[] args) {
		 ANTLRInputStream input = new ANTLRInputStream("y = 6*4 + 
9 /8 / 2.5 + -3.21 * RUBEN; C = 5/9 * F + 32;");
		 CalcLexer lexer = new CalcLexer(input);
		 CommonTokenStream tokens = new CommonTokenStream(lexer);
		 CalcParser parser = new CalcParser(tokens);
		 CollectVarsVisitor my_visitor = new CollectVarsVisitor();
//		 parser.prog();
		 ParseTree tree  = parser.prog();
		 tree.accept(my_visitor);
	 	 System.out.println(my_visitor.vars);
    }

	 public class CollectVarsVisitor extends CalcBaseVisitor<Void> {
	 	HashSet<String> vars = new HashSet<String>();
		@Override
    	public Void visitStmt(CalcParser.StmtContext ctx) {
		TerminalNode id = ctx.ID();
       if(id != null) {
           vars.add(id.getText());
       }
       return super.visitStmt(ctx);
    	}

	 	@Override
    	public Void visitExpr(CalcParser.ExprContext ctx) {
        TerminalNode id = ctx.ID();
        if(id != null) {
            vars.add(id.getText());
        }
        return super.visitExpr(ctx);
    	}
	 }
}

it says

[ruben@manjaro calculator]$ javac Main.java 
Main.java:15: error: non-static variable this cannot be referenced from a 
static context
                 CollectVarsVisitor my_visitor = new CollectVarsVisitor();
                                                 ^
1 error

I have no clue what is the problem, but it is not a standard static 
problem

[toc] | [next] | [standalone]


#34025

FromJoerg Meier <joergmmeier@arcor.de>
Date2016-03-26 21:01 +0100
Message-ID<1w52q64vhga89.szqfwweogyn3.dlg@40tude.net>
In reply to#34024
On Sat, 26 Mar 2016 19:44:53 +0000 (UTC), Popping mad wrote:

> When I try to compile this (example from antlr4 FIWIW)

[...]

> it says

> [ruben@manjaro calculator]$ javac Main.java 
> Main.java:15: error: non-static variable this cannot be referenced from a 
> static context
>                  CollectVarsVisitor my_visitor = new CollectVarsVisitor();

> 1 error

> I have no clue what is the problem, but it is not a standard static 
> problem

The problem is that you are (implicitly) trying to use the instance
variable 'this' from the static block main(String[] args). There are three
possible solutions:

a) move the code to an instance block instead of a static block
b) generate a new instance of Main to be used as a source for the
CollectVarsVisitor you want to make
c) make CollectVarsVisitor itself static so it can be instantiated without
needing an instance of Main.

In case you are unaware of what is happening: CollectVarsVisitor is a
non-static nested class, also called an "inner class". If you want to do
"new CollectVarsVisitor()", you need an instance of Main - you could do
"new Main().new CollectVarsVisitor()" (that would be solution b).

Inner classes have a reference to their 'surrounding' instance and should
be used for cases where an instance of the inner class are only
meaningful/useful in the context of the class that surrounds it.

The alternative are static nested classes (or just "nested classes")
(solution c). You can turn CollectVarsVisitor into a nested class instead
of an inner class simply by changing:

public class CollectVarsVisitor extends CalcBaseVisitor<Void> {

to

public static class CollectVarsVisitor extends CalcBaseVisitor<Void> {

Other than the namespace (from elsewhere, you would refer to
CollectVarsVisitor as "Main.CollectVarsVisitor"), nested classes are first
class citizens and can be used like "normal" classes, as they do not need
an instance of the surrounding class.

Liebe Gruesse,
		Joerg

-- 
Ich lese meine Emails nicht, replies to Email bleiben also leider
ungelesen.

[toc] | [prev] | [next] | [standalone]


#34036

FromPopping mad <rainbow@colition.gov>
Date2016-03-28 13:19 +0000
Message-ID<ndbb17$k7m$2@reader1.panix.com>
In reply to#34025
On Sat, 26 Mar 2016 21:01:58 +0100, Joerg Meier wrote:

> In case you are unaware of what is happening: CollectVarsVisitor is a
> non-static nested class, also called an "inner class". If you want to do
> "new CollectVarsVisitor()", you need an instance of Main - you could do
> "new Main().new CollectVarsVisitor()" (that would be solution b).

why is that the case?
Because it is in the curly braces of Main, or because it is in the file 
itself?

[toc] | [prev] | [next] | [standalone]


#34046

FromEric Sosman <esosman@comcast-dot-net.invalid>
Date2016-03-28 14:59 -0400
Message-ID<ndbupe$kj1$1@dont-email.me>
In reply to#34036
On 3/28/2016 9:19 AM, Popping mad wrote:
> On Sat, 26 Mar 2016 21:01:58 +0100, Joerg Meier wrote:
>
>> In case you are unaware of what is happening: CollectVarsVisitor is a
>> non-static nested class, also called an "inner class". If you want to do
>> "new CollectVarsVisitor()", you need an instance of Main - you could do
>> "new Main().new CollectVarsVisitor()" (that would be solution b).
>
> why is that the case?

     Because every instance of an inner class is associated with --
"belongs to" -- an instance of its containing class. That's what an
inner class *is*: An appendage, dependent, hanger-on, chattel, or
companion of its owner object.

> Because it is in the curly braces of Main, or because it is in the file
> itself?

     Your question makes no sense, which leads me to suspect your
understanding of Java may as yet be inadequate for the tasks you
are trying to undertake.  In other words: Back to the books!

-- 
esosman@comcast-dot-net.invalid
"Don't be afraid of work. Make work afraid of you." -- TLM

[toc] | [prev] | [next] | [standalone]


#34026

FromEric Sosman <esosman@comcast-dot-net.invalid>
Date2016-03-26 16:04 -0400
Message-ID<nd6pps$ee3$1@dont-email.me>
In reply to#34024
On 3/26/2016 3:44 PM, Popping mad wrote:
> When I try to compile this (example from antlr4 FIWIW)
> [...]
> public class Main {
>      public static void main(String[] args) {
>[...]
> 		 CollectVarsVisitor my_visitor = new CollectVarsVisitor();
> [...]
>      }
>
> 	 public class CollectVarsVisitor extends CalcBaseVisitor<Void> {
> [...]
>      	}
> [...]

> it says
>
> [ruben@manjaro calculator]$ javac Main.java
> Main.java:15: error: non-static variable this cannot be referenced from a
> static context
>                   CollectVarsVisitor my_visitor = new CollectVarsVisitor();
>                                                   ^
> 1 error
>
> I have no clue what is the problem, but it is not a standard static
> problem

     CollectVarsVisitor is an "inner class," a nested class each of whose
instances belongs to an instance of the containing class (Main).  You
cannot have a CollectVarsVisitor instance without a Main instance to
own it.  Since the main() method is static, there is no Main instance
around to be the owner of the new CollectVarsVisitor.  And that's why
the compiler complains (in its ever-so-transparent way).

     I'm not quite sure what you're trying to do, but it looks like the
solution might be to use a static nested class:

	public /* => */ static /* <= */ class CollectVarsVisitor ...

If the nested class is truly supposed to be an inner class (belonging
to a Main instance), then you'll need a Main:

	Main my_main = new Main();
	CollectVarsVisitor my_visitor
	    = my_main.new CollectVarsVisitor();

-- 
esosman@comcast-dot-net.invalid
"Don't be afraid of work. Make work afraid of you." -- TLM

[toc] | [prev] | [next] | [standalone]


#34037

FromPopping mad <rainbow@colition.gov>
Date2016-03-28 13:24 +0000
Message-ID<ndbb9g$k7m$3@reader1.panix.com>
In reply to#34026
On Sat, 26 Mar 2016 16:04:07 -0400, Eric Sosman wrote:

> f the nested class is truly supposed to be an inner class (belonging to
> a Main instance), then you'll need a Main:
> 
> 	Main my_main = new Main(); CollectVarsVisitor my_visitor
> 	    = my_main.new CollectVarsVisitor();


Calling for a Class instance from within a class constructor seems like a 
sure fire way to make an infinite loop.

[toc] | [prev] | [next] | [standalone]


#34039

FromArne Vajhøj <arne@vajhoej.dk>
Date2016-03-28 09:50 -0400
Message-ID<ndbcqp$or3$1@gioia.aioe.org>
In reply to#34037
On 3/28/2016 9:24 AM, Popping mad wrote:
> On Sat, 26 Mar 2016 16:04:07 -0400, Eric Sosman wrote:
>> f the nested class is truly supposed to be an inner class (belonging to
>> a Main instance), then you'll need a Main:
>>
>> 	Main my_main = new Main(); CollectVarsVisitor my_visitor
>> 	    = my_main.new CollectVarsVisitor();
>
>
> Calling for a Class instance from within a class constructor seems like a
> sure fire way to make an infinite loop.

Yes.

But that is not the case here, so ...

Arne

[toc] | [prev] | [next] | [standalone]


#34047

FromEric Sosman <esosman@comcast-dot-net.invalid>
Date2016-03-28 15:04 -0400
Message-ID<ndbv1r$kj1$2@dont-email.me>
In reply to#34037
On 3/28/2016 9:24 AM, Popping mad wrote:
> On Sat, 26 Mar 2016 16:04:07 -0400, Eric Sosman wrote:
>
>> f the nested class is truly supposed to be an inner class (belonging to
>> a Main instance), then you'll need a Main:
>>
>> 	Main my_main = new Main(); CollectVarsVisitor my_visitor
>> 	    = my_main.new CollectVarsVisitor();
>
>
> Calling for a Class instance from within a class constructor seems like a
> sure fire way to make an infinite loop.

     For context, from your original post:

     public static void main(String[] args) {
         // ...
         CollectVarsVisitor my_visitor = new CollectVarsVisitor();
         // ...
     }

My suggestion was to replace that one line in the middle with the two
I offered.  Now: Would either of those lines be inside a constructor?
(Hint: Is `public static void main(String[] args)' a constructor?)

     I'm going to repeat an observation I've already made elsethread:
Your grasp of Java is not yet firm enough to allow you to use the
language productively.  Back to the books!

-- 
esosman@comcast-dot-net.invalid
"Don't be afraid of work. Make work afraid of you." -- TLM

[toc] | [prev] | [next] | [standalone]


#34048

FromFredK <fred.l.kleinschmidt@gmail.com>
Date2016-03-28 15:17 -0700
Message-ID<f195eaee-53f0-4e78-9409-c99b7bae1126@googlegroups.com>
In reply to#34047
I don't see why CollectVarsVisitor is even written as an inner class - it does not seem to reference anything in the Main class. Perhaps it should just be a separate class of its own.

[toc] | [prev] | [next] | [standalone]


#34049

FromEric Sosman <esosman@comcast-dot-net.invalid>
Date2016-03-28 18:30 -0400
Message-ID<ndcb3f$6k6$1@dont-email.me>
In reply to#34048
On 3/28/2016 6:17 PM, FredK wrote:
> I don't see why CollectVarsVisitor is even written as an inner class - it does not seem to reference anything in the Main class. Perhaps it should just be a separate class of its own.

     It looked to me like it should probably become a static nested
class instead of an inner class.  If so, it could do just as well
as an entirely separate top-level class -- but it's so short that
the bother of managing an additional file might not be worth it.

     It'd be okay either way, though.

-- 
esosman@comcast-dot-net.invalid
"Don't be afraid of work. Make work afraid of you." -- TLM

[toc] | [prev] | [next] | [standalone]


#34027

FromAndreas Leitgeb <avl@logic.at>
Date2016-03-26 20:17 +0000
Message-ID<slrnnfdro8.456.avl@login.logic.tuwien.ac.at>
In reply to#34024
Popping mad <rainbow@colition.gov> wrote:
> public class Main {
>    public static void main(String[] args) {
>       [...]
>       CollectVarsVisitor my_visitor = new CollectVarsVisitor();
>       [...]
>    }
>    public class CollectVarsVisitor extends CalcBaseVisitor<Void> {
>       [...]
>    }
> }
> it says
> [ruben@manjaro calculator]$ javac Main.java 
> Main.java:15: error: non-static variable this cannot be referenced from a 
> static context
>                  CollectVarsVisitor my_visitor = new CollectVarsVisitor();
>                                                  ^
> 1 error

As you put it, CollectVarsVisitor is an "inner" class of Main.  Inner
classes are classes that are nested inside another class *and* don't have
the "static" keyword. Because of that, to instantiate such a class, the
new must happen from within a *non*-static method of the outer class,
or needs some instance and a dot(".") before the "new".

Probably, the fastest fix is to add "static" keyword to the declaration of
class CollectVarsVisitor (right after "public") and turn in from an "inner"
class back into a nested class (as was likely intended, anyway).

A better fix could be to move class CollectVarsVisitor into its own source
file.

[toc] | [prev] | [next] | [standalone]


#34041

FromArne Vajhøj <arne@vajhoej.dk>
Date2016-03-28 10:10 -0400
Message-ID<ndbe04$rj9$1@gioia.aioe.org>
In reply to#34024
On 3/26/2016 3:44 PM, Popping mad wrote:
> When I try to compile this (example from antlr4 FIWIW)
>

> public class Main {
>      public static void main(String[] args) {

> 		 CollectVarsVisitor my_visitor = new CollectVarsVisitor();

> 	 public class CollectVarsVisitor extends CalcBaseVisitor<Void> {

> it says
>
> [ruben@manjaro calculator]$ javac Main.java
> Main.java:15: error: non-static variable this cannot be referenced from a
> static context
>                   CollectVarsVisitor my_visitor = new CollectVarsVisitor();
>                                                   ^
> 1 error
>
> I have no clue what is the problem, but it is not a standard static
> problem

Other have already pointed out the problem.

But let me try and elaborate.

Or maybe add to the confusion.

:-)

When a class is declared inside another class with static then
it is just another class with an unusual name and more complex
accessibility.

Example:

public class Main1 {
	// note static
	public static class Foobar {
		@Override
		public String toString() {
			return super.toString();
		}
	}
	public void test() {
		// full syntax
		Main1.Foobar a = new Main1.Foobar();
		System.out.println(a);
		// abbreviated syntax
		Foobar b = new Foobar();
		System.out.println(b);
	}
	public static void main(String[] args) {
		Main1 o = new Main1();
		o.test();
	}
}

When it is declared without static, then each instance
belong to an instance of the outer class. And in fact code
can refer to that using classname.this syntax.

Example:

public class Main2 {
	// note not static
	public class Foobar {
		@Override
		public String toString() {
			return super.toString() + "/" + Main2.this.toString();
		}
	}
	public void test() {
		// full syntax
		Main2.Foobar a = this.new Foobar();
		System.out.println(a);
		// abbreviated syntax
		Foobar b = new Foobar();
		System.out.println(b);
	}
	public static void main(String[] args) {
		Main2 o = new Main2();
		o.test();
	}
}

(and your problem as pointed out by several other was that you had
this case and were using the abbreviated syntax with an implicit this
prefix on new - an getting the error because in the static main there
is no this)

Arne

[toc] | [prev] | [next] | [standalone]


#34715

FromRoedy Green <inquiry@mindprod.com>
Date2016-06-29 00:56 -0700
Message-ID<4mv6nbdse2t67aqbht1ofnhvsqnqap9ltt@4ax.com>
In reply to#34024
On Sat, 26 Mar 2016 19:44:53 +0000 (UTC), Popping mad
<rainbow@colition.gov> wrote:

>: non-static variable this cannot be referenced from a 
>static context

see
http://mindprod.com/jgloss/compileerrormessages.html#NONSTATICCANTBEREF

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.java.programmer


csiph-web