How to overcome static referencing errors in Java/basic programming?
Is my program ok?


Well, I guess it works. However, it can be structured far better.

Basic Object Oriented Programming in Java

In Java (and all of this is also true for C#), every object has a type which is represented by a so-called class. We can define operations on each type, which we call methods. Some methods operate on an individual instance of a type. Other operations are not inherently bound to instances, and operate on the whole class. We call this second kind of operations static methods.

Likewise, data can either belong to a specific instance, or is shared across all instances, in which case it's called static. Every method (static and non-static) can refer to static data, because that is shared. However, static methods cannot reference instance data, because a static method can't tell from which instance you'd like the data – and sometimes, no instance may exist at all. Static methods are mostly useful for general helpers.

It is really important to grok the difference between static and non-static methods in order to use Java effectively (the same holds for any other class-based programming language).

Meaning of the main

What is the main and why do we need it? The main originated as a feature of the C programming language. It defines an entry point into the program. At startup, your classes are initialized and then the main methods gets called with the command line arguments in an array as parameter. The main method doesn't return a value (it is void), because returning from it aborts the process.

The main is static because it's a helper method to get your control flow going – it is not coupled to any instance. It is therefore common in a main to create an instance of the surrounding class, and work with that.

Constructors

A constructor is a special method used to initialize a fresh instance. All it usually does is assigning its arguments to the corrects data fields of the instance. It isn't recommended to do the actual work here – put that into another method.

In your code, everything after the initialization can be moved into the main method where it belongs. Note that methods are invoked on a specific instance with the dot operator. The main now looks like:

public static void main(String[] args) {
    Matrix matrix = new Matrix();

    System.out.println("M");
    matrix.printMatrix();

    matrix.transpose();

    System.out.println("M'");
    matrix.printMatrix();
}


Now we are already getting into the code review zone of this answer.

Design spotlights

A method should do one thing only and – no “and”!

Every method should do one thing only. Exaggerated: While a description of your method uses the word “and”, it is doing to much. Split the functionality into more methods. For example, your transpose method does this: “It prints an empty line and swaps columns with rows of the matrix”. Is printing an empty line really necessary in a method called “transpose”?

The same goes for your version of the constructor: “It initialized the matrix and prints it out and transposes it and prints it out again” – but we already cleaned that up above.

Composability

An advantage of having each method doing one concept only makes it easier to compose them in a different way to do new things. There are a few important things that can make this easier:

Don't hardcode stuff – parameterize it

Don't hardcode things that aren't universal constants. Actually, don't hardcode things at all. For example, you assign static int mat_size = 3 – but what if I want to use a 5×5 matrix? You don't provide any functionality that actually depends on the number three. Instead, the size is a property of each instance. Therefore, we'll remove the static modifier, and initialize it in the constructor.

The constructor is another example of hardcoding: The whole test matrix is specified there. It would be better to move that data out of the constructor, and have the constructor take an array as argument instead. I'd rather initialize a new matrix like:

// array literals :) – however, I'm unsure about the exact syntax
double[3][3] testData = { { 1, 0, 0 },
                          { 5, 1, 0 },
                          { 6, 5, 1 } };
Matrix matrix = new Matrix(3, testData);


We can now initialize a matrix with arbitrary other values, not only that specific data set.

Immutability

When objects don't change their internal state over time, programs often get a bit simpler. Mathematics does this as well: When we transpose a matrix M, the M still has its old values. The transposition produces a new and distinct matrix, which we can call M' (you even do this in your printout). There is no reason our transpose method shouldn't return a new matrix either. Now we get something along the lines of:

public Matrix transpose() {
    double[size][size] newData = new double[size][size];

    for(int i = 0; i &lt; size; i++) {
        for(int j = 0; j &lt; i ; j++) {
            newData[i][j] = get(j, i);
            newData[j][i] = get(i, j);
        }
        newData[i][i] = get(i, i);
    }

    return new Matrix(size, newData);
}


This changes our main:

public static void main(String[] args) {
    Matrix matrix = new Matrix();

    System.out.println("M");
    matrix.printMatrix();

    Matrix transposed = matrix.transpose();

    System.out.println("M'");
    transposed.printMatrix();
}


No side effects

When a method has any effect except returning some data, it has side effects. Such effects might be changing the state of some object (thus voiding the point about immutability), or printing out some data. These side effects make it more difficult to combine these methods in a new way.

Specifically, printMatrix is an offender here. Also because it can't be changed to print to anything other than System.out. What happens when I want a string representation to display on a GUI? I can't simply use your awesome Matrix class :(

Here, it would be better to implement the toString() function, which returns a string representation of your object. There is already a default implementation for every object, but we can override it. Then, our main will look like:

public static void main(String[] args) {
    Matrix matrix = new Matrix();

    System.out.println("M");
    System.out.println(matrix.toString());

    Matrix transposed = matrix.transpose();

    System.out.println("M'");
    System.out.println(transposed.toString());
}


That is more ugliness here, but massively clears up the rest of your code. The toString might be:

public String toString() {
    StrinBuilder sb = new StringBuilder();
    for(int i = 0; i &lt; size; i++) {
        for(int j = 0; j &lt; size ; j++) {
            sb.append(" " + (int) get(i, j));
        }
        sb.append("\n");
    }
    return sb.toString();
}
// apologies if I mixed up the StringBuilder API


A closing note on naming things

In Java, names are written in camelCase. Class names are capitalized. Any other names start with a lowercase letter: Matrix refers to a class, while matrix is a local variable, field, or method. As an exception, constants are written all-uppercase and seperated by underscores. Because for normal names the parts of a word are distinguished by capitalization, no underscores are ever used.

It is advisable to use meaningful names like matrix or transformedMatrix, not shortcuts like m or t or m_. Choosing longer names makes it easier to read a piece of code for someone who isn't used to your shortcut notation.