Generic Singleton in Java - java

Why does the following code throws java.lang.InstantiationException: generics.SingletonFoo$A?
public class SingletonFoo {
private static Object _tn;
public static <T> T instance(Class<T> t) {
if (_tn != null) {
return (T) _tn;
}
try {
_tn = t.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return (T) _tn;
}
private class A{
public A() {
}
}
public static void main(String[] args) {
System.out.println(SingletonFoo.instance(A.class));
}
}
Is it related to type erasure somehow and it's not possible to create generic singleton in Java?

Here A is not static class. Which means it contains a reference to the containing SingletonFoo (implicitly), which means you likely can't instantiate it via newInstance.
try to make it static or move it out of the class it if it doesn't need to be inner class.
Solution 1 : make A a static member class
private static class A{
public A() {
}
}
Soution 2:make it outside
public class SingletonFoo {
private static Object _tn;
public static <T> T instance(Class<T> t) {
if (_tn != null) {
return (T) _tn;
}
try {
_tn = t.newInstance();
;
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return (T) _tn;
}
public static void main(String[] args) {
System.out.println(SingletonFoo.instance(A.class));
}
}
class A {
public A() {
}
}

Related

Java accessing static inner class potentially throw NoSuchFieldException

In Java why calling a static nested class won't compile because of a potential NoSuchFieldException and IllegalArgumentEception ?
Here is my classes:
public class DBRef {
public static class CMS_FILE_ROOM extends BuildableDatabaseTable {
public static String _table_name = "cms_file_ROOM";
public static BuildableColumn _ALL = new BuildableColumn._ALL(getCurrentClass());
}
public static SelectQuery SELECT(final BuildableColumn... columnsToSelect) {
return new SelectQuery(columnsToSelect);
}
}
public class SelectQuery extends Query {
public SelectQuery(final BuildableColumn... columnsToSelect) {
super();
for (final BuildableColumn column : columnsToSelect) {
this.columns.add(column.toSQL());
}
}
public Query FROM(final Class<? extends BuildableDatabaseTable> tableClass) throws NoSuchFieldException, IllegalAccessException {
this.froms.add(DatabaseAccesser.toSQL(tableClass));
return this;
}
}
// Method called in both cases just above by some poor designed methods redirection (my bad). But exceptions are catched.
public static String toSQL(final Class<? extends BuildableDatabaseTable> table) {
try {
return (String) table.getField("_table_name").get(null);
} catch (final IllegalAccessException e) {
e.printStackTrace();
} catch (final NoSuchFieldException e) {
e.printStackTrace();
}
return "ERROR";
}
When from anywhere else in my code I do:
SelectQuery lSelectQuery = (SelectQuery) DBRef.SELECT(DBRef.CMS_FILE_ROOM._ALL)
.FROM(DBRef.CMS_FILE_ROOM.class);
I get the following (compile time) error (on the .class call):
I can't find the reason why, I can nest this in a try catch but I'd like to understand why ?

Java cloning abstract objects

I'm wondering if there is any way to do the following. I have an abstract class, Shape, and all its different subclasses and I want to override the clone method. All I want to do in the method is create a new Shape from the toString() of the current one. Obviously I can't do the following because Shape is abstract. Is there another way to do this because overriding clone in every subclass just for a simple name change seems useless.
public abstract class Shape {
public Shape(String str) {
// Create object from string representation
}
public Shape clone() {
// Need new way to do this
return new Shape(this.toString());
}
public String toString() {
// Correctly overriden toString()
}
}
You can try to use reflection:
public abstract class AClonable implements Cloneable{
private String val;
public AClonable(){
}
public AClonable(String s){
val=s;
}
public String toString(){
return val;
}
#Override
public AClonable clone(){
try {
System.out.println(getClass().getCanonicalName());
AClonable b= getClass().getDeclaredConstructor(String.class).newInstance(val);
return b;
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
in the clone() method you call getClass(). Because the ACloneble ist abstract, there call will allways go to the concrete class.
public class ClonebaleOne extends AClonable{
public ClonebaleOne(){
super();
}
public ClonebaleOne(String s) {
super(s);
// TODO Auto-generated constructor stub
}
}
and
public class ClonebaleTwo extends AClonable{
public ClonebaleTwo(){
super();
}
public ClonebaleTwo(String s) {
super(s);
// TODO Auto-generated constructor stub
}
}
and finally
public static void main(String[] args){
AClonable one = new ClonebaleOne("One");
AClonable tow= new ClonebaleTwo("Two");
AClonable clone = one.clone();
System.out.println(clone.toString());
clone = tow.clone();
System.out.println(clone.toString());
}
Output:
ClonebaleOne
One
ClonebaleTwo
Two
But it's more a hack than a solution
[EDIT] my two clones were faster than ;)
[EDIT] To be complete. Another implentation of clone() can be
#Override
public AClonable clone(){
try {
ByteArrayOutputStream outByte = new ByteArrayOutputStream();
ObjectOutputStream outObj = new ObjectOutputStream(outByte);
ByteArrayInputStream inByte;
ObjectInputStream inObject;
outObj.writeObject(this);
outObj.close();
byte[] buffer = outByte.toByteArray();
inByte = new ByteArrayInputStream(buffer);
inObject = new ObjectInputStream(inByte);
#SuppressWarnings("unchecked")
Object deepcopy = inObject.readObject();
inObject.close();
return (AClonable) deepcopy;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
when your abstract class implements Serialazable. There you write your object to disc and create a copy with the value from the disc.
You can't create deep clone of abstract class because they can't be instantiated. All you can do is shallow cloning by using Object.clone() or returning this
#Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
or
#Override
public Object clone() throws CloneNotSupportedException {
return this;
}
An abstract class can act as a reference, and it cannot have an instance so shallow cloning works in this case
OR
As a better approach, you can declare clone() as abstract and ask child class to define it, something like this
abstract class Shape {
private String str;
public Shape(String str) {
this.str = str;
}
public abstract Shape clone();
public String toString() {
return str;
}
}
class Circle extends Shape {
public Circle(String str) {
super(str);
}
#Override
public Shape clone() {
return new Circle("circle");
}
}
Although I doubt it is a good idea, you could use reflection:
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class Test {
public static void main(String[] args) {
Square s1 = new Square("test");
Square s2 = (Square) s1.clone();
// show that s2 contains the same data
System.out.println(s2);
// show that s1 and s2 are really different objects
System.out.println(s1 == s2);
}
public static abstract class Shape {
private String str;
public Shape(String str) {
this.str = str;
}
public Shape clone() {
try {
Class<?> cl = this.getClass();
Constructor<?> cons = cl.getConstructor(String.class);
return (Shape) cons.newInstance(this.toString());
} catch (NoSuchMethodException | SecurityException |
InstantiationException | IllegalAccessException |
IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
#Override
public String toString() {
return str;
}
}
public static class Square extends Shape {
public Square(String str) {
super(str);
}
}
}
You can resolve with reflection:
public abstract class Shape {
private String str;
public Shape() {
}
protected Shape(String str) {
this.str = str;
}
public Shape clone() throws CloneNotSupportedException
{
try {
return (Shape)getClass().getDeclaredConstructor(String.class).newInstance(this.toString());
} catch (Exception e) {
throw new CloneNotSupportedException();
}
}
public String toString() {
return "shape";
}
public class Round extends Shape
{
public Round()
{
super();
}
protected Round(String str) {
super(str);
}
#Override
public String toString() {
return "round";
}
}
main(){
Shape round = new Round();
Shape clone = round.clone();
System.out.println(round);
System.out.println(clone);
}
but - IMO - is a poor implementation and error-prone with a lot of pits; the best use of Cloneable and Object.clone() is to not use them! You have a lot of way to do the same thing (like serialization for deep-clone) and shallow-clone that allow your a better control of flow.

organizing unittests in java/junit for testing classes with common api

I am implementing some elementary sorting algorithms (for the purpose of learning) ,and want to write unittests for them .All the sorting programs have the following common api
...
public static void sort(Comparable[] a);
...
public static boolean isSorted(Comparable[] a);
...
public static boolean isSorted(Comparable[] a),int from ,int to;
...
So,I wrote the following tests for testing the isSorted() method in SelectionSort
public class SelectionSortTests {
String[] a ;
#After
public void tearDown() throws Exception {
a = null;
}
#Test
public void arraySortedSingleElement(){
a = new String[]{"A"};
Assert.assertTrue(SelectionSort.isSorted(a));
}
#Test
public void arraySortedDistinctElements(){
a = new String[]{"A","B","C","D"};
Assert.assertTrue(SelectionSort.isSorted(a));
}
#Test
public void arrayNotSorted(){
a = new String[]{"A","B","C","B"};
Assert.assertFalse(SelectionSort.isSorted(a));
}
...
}
Now I feel that if I were to write tests for say InsertionSort,ShellSort etc ,they would look the same..Only the name of the class under test will change..
So,how should I organize the tests? Is a suite the answer or can I do better using reflection - may be write a driver program to which I can add a list of names of classes to be tested, and the driver invokes runs the common unit tests by passing the classname to it..
I realize this is a common situation..would like to know how this can be handled without spittle or cellotape
UPDATE:
thanks #BevinQ and #Matthew Farwell ,I tried to solve this using Parameterized unit tests.
Used reflection to call the static method ..
Seems to work :) though I think it can still be refactored to avoid duplicate code
#RunWith(Parameterized.class)
public class ParameterizedSortTests {
private Class classToTest;
private Method methodToTest;
public ParameterizedSortTests(String packageName,String classToTest) {
super();
try {
this.classToTest = Class.forName(packageName+"."+classToTest);
} catch (ClassNotFoundException e) {
System.out.println("failed to get class!!");
e.printStackTrace();
}
}
//method return collection of class names to be tested
#Parameterized.Parameters
public static List<Object[]> classesToTest(){
return Arrays.asList(new Object[][]{
{"elemsorts","SelectionSort"} ,
{"elemsorts","InsertionSort"}
});
}
public void setMethod(String method,Class...args){
try {
this.methodToTest = this.classToTest.getMethod(method, args);
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
#Test
public void arrayIsSorted(){
setMethod("isSorted",Comparable[].class);
String[] a = new String[]{"A","B","C","D"};
Boolean arraySorted = null;
try {
arraySorted = (Boolean)this.methodToTest.invoke(null, new Object[]{a});
System.out.println(this.methodToTest+"returned :"+arraySorted);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
Assert.assertTrue(arraySorted);
}
#Test
public void arrayIsNotSorted(){
setMethod("isSorted",Comparable[].class);
String[] a = new String[]{"A","B","C","B"};
Boolean arraySorted = null;
try {
arraySorted = (Boolean)this.methodToTest.invoke(null, new Object[]{a});
System.out.println(this.methodToTest+"returned :"+arraySorted);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
//System.out.println("arraySorted="+arraySorted);
Assert.assertFalse(arraySorted);
}
}
for interface
public abstract class AbstractSortTests {
String[] a ;
#After
public void tearDown() throws Exception {
a = null;
}
protected abstract Sorter getSorter();
#Test
public void arraySortedSingleElement(){
a = new String[]{"A"};
Assert.assertTrue(getSorter().isSorted(a));
}
#Test
public void arraySortedDistinctElements(){
a = new String[]{"A","B","C","D"};
Assert.assertTrue(getSorter.isSorted(a));
}
...
}
public class SelectionSortTests extends AbstractSortTests {
protected Sorter getSorter(){
return SelectionSort.getInstance();
}
}
public class QuickSortTests extends AbstractSortTests {
protected Sorter getSorter(){
return QuickSort.getInstance();
}
}
using reflection it is a bit messier but still do-able. I have not tested this code so might have
a couple of bugs, but have used this method in the past. Using interfaces would be the preferred method in 99% of cases.
public abstract class AbstractSortTests {
String[] a ;
#After
public void tearDown() throws Exception {
a = null;
}
protected abstract Sorter getSorter();
#Test
public void arraySortedSingleElement() throws Exception{
a = new String[]{"A"};
Assert.assertTrue(executeMethod(getSorterClass(), "isSorted", a);
}
#Test
public void arraySortedDistinctElements() throws Exception{
a = new String[]{"A","B","C","D"};
Assert.assertTrue(executeMethod(getSorterClass(), "isSorted", a);
}
private void executeMethod(Class<?> sortClass, String methodName, String[] values) throws Exception{
return sortClass.getDeclaredMethod(methodName, new Class[]{String[].class}).invoke(null, new Object[]{values});
}
...
}
public class SelectionSortTests extends AbstractSortTests {
protected Class<?> getSorterClass(){
return SelectionSort.class;
}
}
As #BevynQ says, you'll make life a lot easier for yourself if you make your methods non-static, and you implement an interface (called Sorter below). The you can easily use Parameterized. This is a very quick example of how to use it, (untested, uncompiled)
#RunWith(Parameterized.class)
public class SorterTest {
#Parameters
public static Iterable<Object[]> data() {
return Arrays.asList(new Object[][] {
{ new SelectionSort() },
{ new BubbleSort() }
});
}
private final Sorter sorter
public SorterTest(Sorter sorter) {
this.sorter = sorter;
}
#Test
public void arraySortedSingleElement(){
String[] a = new String[]{"A"};
Assert.assertTrue(sorter.isSorted(a));
}
#Test
public void arraySortedDistinctElements(){
String[] a = new String[]{"A","B","C","D"};
Assert.assertTrue(sorter.isSorted(a));
}
#Test
public void arrayNotSorted(){
String[] a = new String[]{"A","B","C","B"};
Assert.assertFalse(sorter.isSorted(a));
}
}
why not something like this?
#Test
public void arraySortedDistinctElements(){
a = new String[]{"A","B","C","D"};
Assert.assertTrue(SelectionSort.isSorted(a));
Assert.assertTrue(InsertionSort.isSorted(a));
Assert.assertTrue(QuickSort.isSorted(a));
}
I don't think you have more than 10 different sortings to test. so it should be good.
otherway, you can declare all Sorting classes in Array and load using Class properties.

Create an exception-safe wrapper of a class

I have a legacy class C1, implementing interface I, that may throw some exceptions.
I want to create a class C2, also implementing interface I, that is based on an instance of C1, but catches all exceptions and does something useful about them.
Currently my implementation looks like this:
class C2 implements I {
C1 base;
#Override void func1() {
try {
base.func1();
} catch (Exception e) {
doSomething(e);
}
}
#Override void func2() {
try {
base.func2();
} catch (Exception e) {
doSomething(e);
}
}
...
}
(Note: I could also make C2 extend C1. This does not matter for the current question).
The interface contains many functions, so I have to write the same try... catch block again and again.
Is there a way to reduce the amount of code duplication here?
You can make a Proxy, it could actually be generic
interface I1 {
void test();
}
class C1 implements I1 {
public void test() {
System.out.println("test");
throw new RuntimeException();
}
}
class ExceptionHandler implements InvocationHandler {
Object obj;
ExceptionHandler(Object obj) {
this.obj = obj;
}
#Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
return method.invoke(obj, args);
} catch (Exception e) {
// need a workaround for primitive return types
return null;
}
}
static <T> T proxyFor(Object obj, Class<T> i) {
return (T) Proxy.newProxyInstance(obj.getClass().getClassLoader(), new Class[] { i },
new ExceptionHandler(obj));
}
}
public class Test2 {
public static void main(String[] args) throws Exception {
I1 i1 = ExceptionHandler.proxyFor(new C1(), I1.class);
i1.test();
}
}

Throw my own exceptions?

I have defined my own expection class:
public class ProduktException extends Exception {
public ProduktException(String msg){
//null
}
public static void throwProduktNotCreatedException() throws ProduktException {
throw new ProduktException("Cannot be created!");
}
public static void throwProduktNotDeletedException () throws ProduktException {
throw new ProduktException("Cannot be deleted!");
}
}
My Problem is I do not know how to throw them when I try:
try {
...
} catch(ProduktNotDeletedException e) {
e.toString();
}
That does not work... But I want to have these structure! What is wrong?
I appreaciate your answer!!!
UPDATE:
My Problem is, I do not want to create several Exception Klasses I want to have all Exceptions in one class. Is there possibly a solution for that?
If you need to differentiate between different kinds of exceptions, just create 2 different exceptions, maybe something like:
public class ProduktException extends Exception
{
public ProduktException(String msg){
//null
}
}
Then have:
public class ProduktNotDeletedException extends ProduktException
{
....
}
and
public class ProduktNotCreatedException extends ProduktException
{
....
}
Then you can catch one or the other, or both.
try {
...
} catch(ProduktNotDeletedException e1) {
e1.toString();
} catch(ProduktNotCreatedException e2) {
e2.toString();
}
EDIT:
For a single class what I mean is:
public class ProduktException extends Exception {
boolean notDeleted;
boolean notCreated;
public ProduktException(String msg){
super(msg);
}
public boolean isNotDeleted() {
return(notDeleted);
}
public boolean isNotCreated() {
return(notCreated);
}
public static void throwProduktNotCreatedException() throws ProduktException {
ProduktException e = new ProduktException("Cannot be created!");
e.notCreated = true;
throw e;
}
public static void throwProduktNotDeletedException () throws ProduktException {
ProduktException e = new ProduktException("Cannot be deleted!");
e.notDeleted = true;
throw e;
}
}
Then in your try/catch:
try {
...
} catch(ProduktException e) {
e.toString();
if(e.isNotCreated()) {
// do something
}
if(e.isNotDeleted()) {
// do something
}
}
You need to either catch ProduktException, e.g.
try {
...
} catch (ProduktException e) {
e.toString();
}
or declare subtypes, e.g.
public ProduktNotDeletedException extends ProduktException
You'll probably want to pass the message in the constructor up, so add the following in your constructor:
super(msg);
The Syntax given below.
class RangeException extends Exception
{
String msg;
RangeException()
{
msg = new String("Enter a number between 10 and 100");
}
}
public class MyCustomException
{
public static void main (String args [])
{
try
{
int x = 1;
if (x < 10 || x >100) throw new RangeException();
}
catch(RangeException e)
{
System.out.println (e);
}
}
}
What you could do if you don't want to create multiple subclasses of your ProduktException for each different type of exception you need to throw is to include a code in the exception which will let you know what is wrong. Something like this:
public class ProduktException extends Exception {
private Code exceptionCode;
private String message
public ProduktException(Code code, String msg){
this.message = msg;
this.exceptionCode = code;
}
//Getters and setters for exceptionCode and message
}
Code can be an enum so that your application can know that each code corresponds to a specific "problem" (product not created, product not deleted, etc.). You can then throw your exceptions like this
throw new ProduktException(Code.PRODUCT_NOT_CREATED,
"Error while creating product");
And when you catch it you can differentiate based on the code.
catch (ProduktException ex) {
if (ex.getExceptionCode().equals(Code.PRODUCT_NOT_CREATED)) {
...
}
else {
...
}
}

Categories