2

The issue I'm having is, while I believe that I've have set up everything correctly in the constructor, when I try to call the instance variable from of my new Letter instance fromto I seem to keep getting an error saying that the compiler can not find variable fromto. The goal is to get Dylan to appear in with the Text.

public class Letter {
    private String from; // Sets from instance variable to be stored
    private String to; /// Sets to instance vaariable to be stored


    public Letter(String from, String to) {
        this.from = from;
        this.to = to;

    }
    public Letter() {

        Letter fromto = new Letter("Dylan", "April");

    }

    public static void main(String[] args) {
        System.out.println("Dear " + fromto.from);

    }

}
Anthony Accioly
  • 21,918
  • 9
  • 70
  • 118
user2872518
  • 53
  • 1
  • 3
  • 8
  • 2
    Your `public Letter()` is a constructor. You don't instantiate your object from a constructor. You do it from another class. In order for the program to run, it needs to be places in a `main` method. – Paul Samsotha Oct 13 '13 at 23:46
  • 1
    For future reference: It's better to edit your question if it's unclear or people ask for more information. It's better to post a new question if you're actually asking about something different. – chrylis -cautiouslyoptimistic- Oct 13 '13 at 23:48

4 Answers4

6

First of all, you should probably learn more about variable scope in Java. (Reading Sun's tutorials about Object-oriented Java-programming is probably a good idea)

The problem here is that the variable fromto is declared in a constructor and thus is only available from the scope of the constructor. Instead, get rid of that constructor (unless you really want to keep it, in which case you should make sure to initialize your from and to variables properly) and move the variable to your main function.

public class Letter {
    private String from; // Sets from instance variable to be stored
    private String to; /// Sets to instance vaariable to be stored


    public Letter(String from, String to) {
        this.from = from;
        this.to = to;

    }
    public static void main(String[] args) {
        Letter fromto = new Letter("Dylan", "April");
        System.out.println("Dear " + fromto.from);
    }

}
Simon Forsberg
  • 13,086
  • 10
  • 64
  • 108
  • Well thank you for the help. Our school has implemented a new teaching method which involves learning it ourselves and showing up Monday with questions. The idea being less class time learning and more time clarifying and working on difficulties. On a side note, why didn;t it work before? If I made it public doesn't that mean the values can be used? – user2872518 Oct 13 '13 at 23:47
  • 1
    @user2872518 The constructor was public which means that **it [the constructor]** can be used. However, the `Letter fromto` variable is declared as a **local variable** within a **method**. Local variables can **never** be accessed from outside the method (or more precisely, *code-block*) that they are declared in. – Simon Forsberg Oct 13 '13 at 23:50
3

You need to instantiate your Letter in the right scope. If you only need it inside the main method, the best place to create your instance is right at the beginning of the method block:

public class Letter {

    private String from; // Sets from instance variable to be stored
    private String to; /// Sets to instance vaariable to be stored

    public Letter(String from, String to) {
        this.from = from;
        this.to = to;

    }

    public Letter() {
    }

    public static void main(String[] args) {
       Letter letter = new Letter("Dylan", "April");
       System.out.println("Dear " + letter.from);
    }

}

About the no-args constructor, it is a good practice to declare one if the instance variables from and to are optional, so that you can also instantiate letter with the syntax new Letter(). If you do not declare any constructors, the compiler provides a empty constructor by default.

Actually, whenever you can, it is a good thing to follow JavaBeans conventions. Quoting Wikipedia:

  • The class must have a public default constructor (no-argument). This allows easy instantiation within editing and activation frameworks.
  • The class properties must be accessible using get, set, is (used for boolean properties instead of get) and other methods (so-called accessor methods and mutator methods), following a standard naming convention. This allows easy automated inspection and updating of bean state within frameworks, many of which include custom editors for various types of properties. Setters must receive only one argument.
  • The class should be serializable. It allows applications and frameworks to reliably save, store, and restore the bean's state in a fashion independent of the VM and of the platform.
Anthony Accioly
  • 21,918
  • 9
  • 70
  • 118
  • It is not always a good thing to follow JavaBeans conventions, see [this question](http://stackoverflow.com/questions/3114903/are-java-beans-as-data-storage-classes-bad-design) – Simon Forsberg Oct 14 '13 at 14:33
3

You need to first create a new instance of your Letter class before you can invoke fields and getter/setter-methods on that instance/object.

public static void main(String[] args)
{
    Letter myLetter = new Letter();
    System.out.println(myLetter.from);
}

Note the call on your private field from only succeeds as main is defined in the same class and therefore the created myLetter provides access to the field.

In practice you would define public setters and getters to access the private field.

Anthony Accioly
  • 21,918
  • 9
  • 70
  • 118
Roman Vottner
  • 12,213
  • 5
  • 46
  • 63
0

Remove

 public Letter(){

  Letter fromto= new Letter("Dylan", "April");

 }

then:

public static void main(String[] args){
Letter fromto= new Letter("Dylan", "April");
  System.out.println("Dear " + fromto.from);

  } 
Victor
  • 16,609
  • 71
  • 229
  • 409