Read only classes/methods - java

In preparing for an interview, someone mentioned knowing how to make a class/method in java read-only. I've been doing a bit of searching, but haven't found anything really concrete.
Maybe this question is simpler to answer than I'm making it out to be, but what would be a way to make a class or method read-only in java?

The following code will ensure that your class is always READ ONLY, but if you find any loop hole, please post it here.
import java.io.Serializable;
final public class ImmutableClass implements Cloneable,Serializable {
private static final long serialVersionUID = 6488148163144293060L;
private static volatile ImmutableClass instance;
private ImmutableClass() {
// no-op
System.out.println("instance created : " + this.hashCode());
}
/**
* Lazy Instantiation
*
* #return
*/
public static ImmutableClass getInstance() {
if (instance == null) {
synchronized (ImmutableClass.class) {
System.out.println("aquired lock");
if (instance == null) {
instance = new ImmutableClass() {
};
}
System.out.println("released lock");
}
}
return instance;
}
public Object readResolve() {
System.out.println("readResolve()");
return getInstance();
}
#Override
public Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
}

The Read-only class means, we are talking about "IMMUTABLE" concept.
The following example depicts the same:
public class ImmutableString {
static String upcase(String s) {
return s.toUpperCase(); // here local variable s vanishes
// it return the value to a new String object
}
public static void main(String[] args) {
String s = new String("abc");
System.out.println(s); //abc
String s1 = upcase(s);
System.out.println(s1); //ABC
System.out.println(s); //abc
}
}

Lets Say you want a read only version of an object,
case 1: if your class contains fields which are not pointers to any other objects eg:
public class Person{
private String name;
//Getters n Setters
}
in this case, you can return a copy of this class, write a constructor that accepts Person, any one who wants to get a Person object will have a copy of this object so any Setter operations wont effect the original object(Strings are immutable)
Case 2: in case your object contains a pointer to another object or list or map
in this case make classes implement an interface which has only read-only methods(Getters) and wherever you are returning the object, change it to return this interface, so client will have access to only read-only methods
eg:
class Person implements ReadOnly{
String name;
.. assume pointers also in here
// Getter n Setters
public PersonReadOnly(){
return this;
}
}
interface PersonReadOnly {
public String getName();
}

Simple rule: Don't have any public fields and No public setter methods.
For example, see class below:
final class AReadOnlyClass
{
private int anInt;
public int GetAnInt()
{
return anInt;
}
}

Related

Is it possible to use toString on undeclared object?

I want to print "None" value for undeclared objects instead of null. Is it possible?
public class class1 {
class2 c2;
public static void main(String[] args) {
class1 c1=new class1();
System.out.println(c1.c2);
}
}
class class2{
public String toString(){
if(this==null){
return "None";
}else{
return "Correct";
}
}
}
Edit: I have added the code. This code prints:
null
But I want to print "None". What should I do?
The utility class Objects offers a lot of useful methods. There's for example Objects#toString(Object) and Objects#toString(Object, String).
final String s = Objects.toString(obj, "None");
After your edit: the this reference is never null, therefore this == null will always be false. You need to handle the null-check outside of your class. Normally, String.valueOf will be called when converting an object to a string. This method handles null references, not the class itself. You'd have to manually convert your object to a string first (with the utility described above).
You'd need to change your code:
public class Class1 {
Class2 c2;
public static void main(String[] args) {
Class1 c1 = new Class1();
System.out.println(Objects.toString(c1.c2, "None"));
}
}
class Class2 {
#Override
public String toString(){
return "Correct";
}
}
You can always create a wrapper around Objects#toString(Object,String) to avoid specifying the default value over and over again:
public final class MyObjects {
private MyObjects(){}
public static String toString(final Object obj) {
return Objects.toString(obj, "None");
}
}

How to enable enum inheritance

I'm writing a library, which has a predefined set of values for an enum.
Let say, my enum looks as below.
public enum EnumClass {
FIRST("first"),
SECOND("second"),
THIRD("third");
private String httpMethodType;
}
Now the client, who is using this library may need to add few more values. Let say, the client needs to add CUSTOM_FIRST and CUSTOM_SECOND. This is not overwriting any existing values, but makes the enum having 5 values.
After this, I should be able to use something like <? extends EnumClass> to have 5 constant possibilities.
What would be the best approach to achieve this?
You cannot have an enum extend another enum, and you cannot "add" values to an existing enum through inheritance.
However, enums can implement interfaces.
What I would do is have the original enum implement a marker interface (i.e. no method declarations), then your client could create their own enum implementing the same interface.
Then your enum values would be referred to by their common interface.
In order to strenghten the requirements, you could have your interface declare relevant methods, e.g. in your case, something in the lines of public String getHTTPMethodType();.
That would force implementing enums to provide an implementation for that method.
This setting coupled with adequate API documentation should help adding functionality in a relatively controlled way.
Self-contained example (don't mind the lazy names here)
package test;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<HTTPMethodConvertible> blah = new ArrayList<>();
blah.add(LibraryEnum.FIRST);
blah.add(ClientEnum.BLABLABLA);
for (HTTPMethodConvertible element: blah) {
System.out.println(element.getHTTPMethodType());
}
}
static interface HTTPMethodConvertible {
public String getHTTPMethodType();
}
static enum LibraryEnum implements HTTPMethodConvertible {
FIRST("first"),
SECOND("second"),
THIRD("third");
String httpMethodType;
LibraryEnum(String s) {
httpMethodType = s;
}
public String getHTTPMethodType() {
return httpMethodType;
}
}
static enum ClientEnum implements HTTPMethodConvertible {
FOO("GET"),BAR("PUT"),BLAH("OPTIONS"),MEH("DELETE"),BLABLABLA("POST");
String httpMethodType;
ClientEnum(String s){
httpMethodType = s;
}
public String getHTTPMethodType() {
return httpMethodType;
}
}
}
Output
first
POST
Enums are not extensible. To solve your problem simply
turn the enum in a class
create constants for the predefined types
if you want a replacement for Enum.valueOf: track all instances of the class in a static map
For example:
public class MyType {
private static final HashMap<String,MyType> map = new HashMap<>();
private String name;
private String httpMethodType;
// replacement for Enum.valueOf
public static MyType valueOf(String name) {
return map.get(name);
}
public MyType(String name, String httpMethodType) {
this.name = name;
this.httpMethodType = httpMethodType;
map.put(name, this);
}
// accessors
public String name() { return name; }
public String httpMethodType() { return httpMethodType; }
// predefined constants
public static final MyType FIRST = new MyType("FIRST", "first");
public static final MyType SECOND = new MyType("SECOND", "second");
...
}
Think about Enum like a final class with static final instances of itself. Of course you cannot extend final class, but you can use non-final class with static final instances in your library. You can see example of this kind of definition in JDK. Class java.util.logging.Level can be extended with class containing additional set of logging levels.
If you accept this way of implementation, your library code example can be like:
public class EnumClass {
public static final EnumClass FIRST = new EnumClass("first");
public static final EnumClass SECOND = new EnumClass("second");
public static final EnumClass THIRD = new EnumClass("third");
private String httpMethodType;
protected EnumClass(String name){
this.httpMethodType = name;
}
}
Client application can extend list of static members with inheritance:
public final class ClientEnum extends EnumClass{
public static final ClientEnum CUSTOM_FIRST = new ClientEnum("custom_first");
public static final ClientEnum CUSTOM_SECOND = new ClientEnum("custom_second");
private ClientEnum(String name){
super(name);
}
}
I think that this solution is close to what you have asked, because all static instances are visible from client class, and all of them will satisfy your generic wildcard.
We Fixed enum inheritance issue this way, hope it helps
Our App has few classes and each has few child views(nested views), in order to be able to navigate between childViews and save the currentChildview we saved them as enum inside each Class.
but we had to copy paste, some common functionality like next, previous and etc inside each enum.
To avoid that we needed a BaseEnum, we used interface as our base enum:
public interface IBaseEnum {
IBaseEnum[] getList();
int getIndex();
class Utils{
public IBaseEnum next(IBaseEnum enumItem, boolean isCycling){
int index = enumItem.getIndex();
IBaseEnum[] list = enumItem.getList();
if (index + 1 < list.length) {
return list[index + 1];
} else if(isCycling)
return list[0];
else
return null;
}
public IBaseEnum previous(IBaseEnum enumItem, boolean isCycling) {
int index = enumItem.getIndex();
IBaseEnum[] list = enumItem.getList();
IBaseEnum previous;
if (index - 1 >= 0) {
previous = list[index - 1];
}
else {
if (isCycling)
previous = list[list.length - 1];
else
previous = null;
}
return previous;
}
}
}
and this is how we used it
enum ColorEnum implements IBaseEnum {
RED,
YELLOW,
BLUE;
#Override
public IBaseEnum[] getList() {
return values();
}
#Override
public int getIndex() {
return ordinal();
}
public ColorEnum getNext(){
return (ColorEnum) new Utils().next(this,false);
}
public ColorEnum getPrevious(){
return (ColorEnum) new Utils().previous(this,false);
}
}
you could add getNext /getPrevious to the interface too
#wero's answer is very good but has some problems:
the new MyType("FIRST", "first"); will be called before map = new HashMap<>();. in other words, the map will be null when map.add() is called. unfortunately, the occurring error will be NoClassDefFound and it doesn't help to find the problem. check this:
public class Subject {
// predefined constants
public static final Subject FIRST;
public static final Subject SECOND;
private static final HashMap<String, Subject> map;
static {
map = new HashMap<>();
FIRST = new Subject("FIRST");
SECOND = new Subject("SECOND");
}
private final String name;
public Subject(String name) {
this.name = name;
map.put(name, this);
}
// replacement for Enum.valueOf
public static Subject valueOf(String name) {
return map.get(name);
}
// accessors
public String name() {
return name;
}

How can I access a field of a local-inner class from another method?

Consider the field bar of the local-inner class MyValue:
public class C {
public static void main(String x[]) {
class MyValue implements IValue {
String bar = "bar";
public String getValue() {
return "my value";
}
}
MyValue myValue = new MyValue();
D d = new D();
d.accessBar(myValue);
}
}
which implements the IValue interface:
interface IValue {
public String getValue();
}
How can I access the field bar from another function (outside of main), let's say in class D:
class D {
public void accessBar(IValue value) {
String info = value.getValue() + value.bar;
}
}
If you need to access the pass key of a ship and you only have the IShip interface, then IShip should have a getPassKey() method, basically. Even if you could cast to ShipAddress within the method, you shouldn't do so - you should make the parameter type for the calculatedInfo method suitable for all the operations the method requires.
You could access it via reflection, but that would be horribly brittle and I'd strongly recommend that you don't do that.

String s1=new String("demo"); While printing why does it give output as the given string?

If we create a String like below and print the value:
String s=new String("demo");
System.out.println(s);
...the output is:
demo
Good. This is the expected output. But here String is a class. Remember that. Below is another example. For example, take a class like this:
class A
{
public static void main (String args[])
{
A a =new A();
A a1=new A("hi"); //we should create a Constructor like A(String name)
System.out.println(a1); //here O/P is address
}
}
My doubt is that I created the A instance in the same way I created the new String object, and I printed that object. So why does it not print the given String for the instance of A?
You need to override the Object#toString() in your class. By default, the toString() method of Object is called.
Also, to print the value, you just need to override the method as internally a call will be made to the toString() method when this statement is executed.
System.out.println(a1);
Sample overriden toString() method.
#Override
public String toString() {
// return a string value
return "The String representation of your class, as per your needs";
}
You have to override toString() method in your class the way you want to print something when call System.out.println();. In String class toString() method has override and you will get out put above due to that.
As pointed out already, you need to override the default toString() method inherited from the Object class. Every class automatically extends the Object class, which has a rather simple toString(), which can't know how to turn your particular object into a String. Why should it, especially if your class is arbitrarily complex? How is it supposed to know how to turn all your class's fields into a "sensible" string representation?
In the toString() of your class, you need to return the string that you want to represent your class with. Here is a simple example:
class A {
String foo;
public A(String foo) {
this.foo = foo;
}
public String toString() {
return foo;
}
}
public class sample {
public static void main(String[] args) {
A a = new A("Hello world!");
System.out.println(a);
}
}
String is a class whose purpose is to hold a string value and will return that value if referenced. When you use other classes, you will usually want to add other behavior. If you want to use the class to hold different values that you can set (on object creation or later in processing) you may want to use "setter" and "getter" methods for such values.
Here is an example:
public class Snippet {
private static final String C_DEFAULT_VALUE = "<default value>";
private String name;
private static Snippet mySnippet;
public Snippet() {
}
public Snippet(String value) {
setName(value);
}
/**
* #param args
*/
public static void main(String[] args) {
if (args != null && args.length > 0) {
mySnippet = new Snippet(args[0]);
} else {
mySnippet = new Snippet(C_DEFAULT_VALUE);
}
System.out.println(mySnippet.getName());
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

Order of Fields returned by Class.getFields()

Javadoc for Class.getFields() say: "The elements in the array returned are not sorted and are not in any particular order."
Any hints on how the order actually is determined? Is it possible that when I execute this method twice, I get fields in different order? In other words, is the order stable for given compiled class, or even between compilations of the same source file?
It should be stable, and for Oracle's JVM its the order they are declared, but you should not rely on this.
You should base lookup on the field's name (and possibly declaring class) rather than position.
On my JVM, at least,
Class.getFields() returns fields in declaration order.
Class.getMethods(), on the other hand, doesn't always. It returns them in (I believe) the order the classloader sees the strings. So if two classes have the same method name, the second-loaded class will return the shared method name before its other methods.
javap confirms the compiler wrote both fields and methods in declaration order.
See the output of this code sample.
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class OrderTest {
public static void main(String[] args) {
// fields are in declaration order
for (Field field : C1.class.getDeclaredFields()) {
System.out.println(field.getName());
}
for (Field field : C2.class.getDeclaredFields()) {
System.out.println(field.getName());
}
// methods, on the other hand, are not necessarily in declaration order.
for (Method method : C1.class.getDeclaredMethods()) {
System.out.println(method.getName());
}
for (Method method : C2.class.getDeclaredMethods()) {
System.out.println(method.getName());
}
}
}
class C1 {
public int foo;
public int bar;
public int getFoo() { return foo; }
public int getBar() { return bar; }
}
class C2 {
public int bar;
public int foo;
public int getBar() { return bar; }
public int getFoo() { return foo; }
}
on my JVM (1.7.0_45, Windows) this returns
foo
bar
bar
foo
getFoo
getBar
getFoo
getBar
Create a helper method that returns a sorted list, and use that instead whenever you need the list of fields. Or lookup by name instead of index.
An natural order of properties offers the Ujorm framework with its key-value objects using the readKeys() method.
Each item of the result have got similar features like the Field including reading and writting values from/to the object. For example see the next code:
public class User extends AbstractUjo implements Serializable {
/** Factory */
private static final KeyFactory<User> f = newFactory(User.class);
/** Keys: */
public static final Key<User, Long> PID = f.newKey();
public static final Key<User, Integer> CODE = f.newKey();
public static final Key<User, String> NAME = f.newKey();
public static final Key<User, Double> CASH = f.newKey();
static {
f.lock();
}
// Setters:
public void setPid(Long pid) {
PID.setValue(this, pid);
}
public void setCode(Integer code) {
CODE.setValue(this, code);
}
public void setName(String name) {
NAME.setValue(this, name);
}
public void setCash(Double cash) {
CASH.setValue(this, cash);
}
// Getters ...
}
The natural order of keys can be iterated by:
for (Key key : new User().readKeys()) {
System.out.println("Key: " + key);
}
See the documentation for more information.

Categories

Resources