Some Sentences about Java


There is nothing new in this article. I just collected some trivial statements which may not be trivial for some of the junior programmers programmers. Boring old stuff.

If you happen all of these things you know more about Java than the average house wife. I do not know if there is point to know all of these. You can be a fairly good Java programmer if you do not know some of these features. However a lot of new information in this article probably indicates you have room to develop.

There are 4 different protection types

in Java (not three). These are private, package private, protected and public. If you do not specify any protection modifier when you define an element in a class it will be package private (and not public and not protected).

4 levels

There are four levels of protection in Java.

On the other hand if you do not specify protection modifier in front of a method declaration in an interface: it will be public. You may specify it to be explicitly public but it does not have effect on Java and SONAR will not like you doing so.
Protection is Transitive

Protection is Transitive

My opinion about Java allowing you to optionally write public in front of a method in an interface is that this is a technology mistake.

Similarly you can write final in front of a field in an interface, or even static. It may imply that they could be non-static or non-final: not true. Fields of an interface are final and static. Always.

Protected and package private are not the same

Package private (or default) protection will let other classes of the same package access to the method or field. Protected methods and fields can be used from
classes in the same package (so far the same as package private) and in addition to that it can be used from other classes that extend the class containing the protected field or method.

Protected is transitive

If there are three packages a, b and c, each containing a class named A, B and C so that B extends A and C extends B then the class C can access the protected fields and methods of A.

package a;

public class A {
	protected void a() {

	}
}
package b;

import a.A;

public class B extends A {
	protected void b() {
		a();
	}
}
package c;

import b.B;

public class C extends B {
	protected void c() {
		a();
	}
}

Interface can not define protected methods

Many thinks that you can also define protected methods in an interface. When programming the compiler makes it obvious fast and brutally: you can not. Btw: this is why I think that allowing the public keyword in an interface is a technology mistake: it makes people think that it could also be something else as well.

Private is the new public

Private is the new public

If you want to declare a protected method in an interface, you probably did not understand encapsulation.

Private is not that private

Private variables and methods are visible inside the compilation unit. If that sounds too cryptic: in the same Java file (almost). This is a bit more than “in the class where they are defined”. They can also be seen from classes and interfaces that are in the same compilation unit. Inner and nested classes can see private fields and methods of the class enclosing them. However enclosing classes can also see the private methods and fields of the classes they enclose down to any depth.

package a;

class Private {
	private class PrivateInPrivate {
		private Object object;
	}

	Object m() {
		return new PrivateInPrivate().object;
	}
}

This latter is not widely known. As a matter of fact it is rarely useful.

Private is class level not object

If you can access a variable or method you can access it no matter which object it belongs to. If this.a is accessible then another.a is also accessible assumed that another is an instance of the same class. Objects that are instances of the same class can fool around with each others variables or methods. Rarely makes sense to have such a code though. A real life exception is equals() (as generated by Eclipse, lines 15 and 18):

package a;

public class PrivateIsClass {
	private Object object;

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		PrivateIsClass other = (PrivateIsClass) obj;
		if (object == null) {
			if (other.object != null)
				return false;
		} else if (!object.equals(other.object))
			return false;
		return true;
	}
}

Static classes may have many instances

Protection is not object level. It is class level.

Protection is not object level. It is class level.

Classes that are not supposed to have any instances are usually called utility classes. They contain only static fields and static methods and the only constructor is private, not invoked from any of the static methods of the class. In Java 8 you can have such a beasts implemented in interfaces, since Java 8 interfaces can have static methods in it. I am not convinced that we should use that feature instead of utility classes. I am not absolutely convinced that we should use utility classes at all.

Static classes are always inside in another class (or interface). They are nested classes. They are static and just as static methods can not access instance methods and fields of the class similarly a static nested class can not access the instance methods and fields of the embedding class. That is because nested classes do not have a reference (pointer if you like) to an instance of the embedding class. Inner classes, as opposed to nested classes are non static and can not be created without an instance of the embedding class. Each instance of an inner class has a reference to exactly one instance of the embedding class and thus an inner class can access instance methods and fields of the embedding class.

Because of this you can not create an inner class without an instance of the surrounding class. You need not specify it though if this is the current object, a.k.a this. In that case you can write new, which is, in this case, just a short form for this.new. In a static environment, for example from a static method you have to specify which instance of the enclosing class should the inner class created with. See the line 10:

package a;

class Nesting {
	static class Nested {}
	class Inner {}
	void method(){
		Inner inner = new Inner();
	}
	static void staticMethod(){
		Inner inner = new Nesting().new Inner();
	}
}

Anonymous classes can access only final variables

Variable has to be effective final

Variable has to be effective final


When an anonymous class is defined inside a method, it can access local variables if they are final. But saying that is vague. They have to be declared final and they also have to be effective final. This is what is relaxed a bit in Java 8. You need not declare such variables as final but they still have to be effective final.
Java 8 does not require final, only effective final

Java 8 does not require final, only effective final

Why do you need to declare something final, when it has to be checked being that anyway? Like method arguments: they also have to be final. You say that this is not a requirement of Java? Well, you are right. It is a requirement of programming in good style.

3 thoughts on “Some Sentences about Java

  1. Kofa

    Regarding ‘Anonymous classes can access only final variables’
    In reality, this is true for all inner classes – see JLS v3 (Java 5) p.182:
    Any local variable, formal method parameter or exception handler parameter used but not declared in an inner class must be declared final. Any local variable, used but not declared in an inner class must be definitely assigned (§16) before the body of the inner class.
    Inner classes include local (§14.3), anonymous (§15.9.5) and non-static member classes (§8.5).

    WIth JLS8, the definition has been updated:
    An inner class is a nested class that is not explicitly or implicitly declared static.
    An inner class may be a non-static member class (§8.5), a local class (§14.3), or an anonymous class (§15.9.5). A member class of an interface is implicitly static (§9.5) so is never considered to be an inner class.​

    And it also relaxes the requirement, as you, rightly, pointed it out (effectively final):
    Any local variable, formal parameter, or exception parameter used but not declared in an inner class must either be declared final or be effectively final (§4.12.4), or a compile-time error occurs where the use is attempted.
    Any local variable used but not declared in an inner class must be definitely assigned (§16 (Definite Assignment)) before the body of the inner class, or a compile-time error occurs.
    Similar rules on variable use apply in the body of a lambda expression (§15.27.2).

    Like

    Reply

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.