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 ?
Related
I am trying to get class resolved to specific type based on enum type.
public enum PipelineType {
A(X.class, XConfig.class),
B(Y.class, YConfig.class);
public final Class<?> pipelineClazz;
public final Class<?> pipelineConfigClazz;
PipelineType(Class<?> pipelineClass,
Class<?> pipelineConfigClazz) {
this.pipelineClazz = pipelineClass;
this.pipelineConfigClazz = pipelineConfigClazz;
}
public Object getPipelineClassObject() {
try {
return this.pipelineClazz.newInstance(); // is there a way to get the specifc class object based on Enum PipelineType.A get X and XConfig object.
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
}
Am i doing something wrong here?
Add a Supplier<?> to the constructor.
enum PipelineType {
X(() -> new XType()),
Y(() -> new YType());
Supplier<?> create;
private PipelineType(Supplier<?> creator) {
create = creator;
}
public <T> T createPipelineObject() {
return (T)create.get();
}
}
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() {
}
}
I have some libraries from external company, I want to use this API. I try to implement calling this API, my logic should call the same method name. I have duplicate codes, I want to avoid to do this. I'm beginner and subjects like interfaces, polymorphism are little bit difficult to me.
public void modPeople(Object person)
{
if (person instanceof com.company.persontype1)
{
com.company.persontype1 fireman = (com.company.persontype1) person;
String name = fireman.getName();
if (name!=null ) {
...
fireman.set_name();
fireman.save();
}
permissions = fireman.get_Permissions();
...
permissions = fixperm (permissions);
fireman.set_Permissions();
};
if (person instanceof com.company.persontype2)
{
com.company.persontype2 nurse = (com.company.persontype2) person;
String name = nurse.getName();
if (name!=null ) {
...
nurse.set_name();
nurse.save();
}
permissions = nurse.get_Permissions();
...
permissions = fixperm (permissions);
nurse.set_Permissions();
};
}
First of all I should mention that the methodology which you requested in your question is called "Duck Typing". Generally this technology is possible in Java (see below the example) but it's not widely used in Java. There could be performance hits etc. It would be much better to introduce a proper inheritance/interface level instead.
Also the provided example don't deal with exceptions properly etc. It's just a quick and quite dirty "demostration of the technology". Feel free to adapt it for your needs.
It's Java7 (for multi-catch clauses, you may refactor this with ease).
ISomeIterface.java (it contains all common methods implemented by classes which are used in your "bad code"):
package org.test;
public interface ISomeInterface {
public String getName();
public void setName(String _name);
public void save();
// specify other common methods
}
ReflectCaller.java:
package org.test1;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.NoSuchElementException;
import org.test.ISomeInterface;
public class ReflectCaller {
private final Method[] methods = ISomeInterface.class.getDeclaredMethods();
private final Map<Class<?>, Method[]> maps = new HashMap<Class<?>, Method[]>();
public void inspectClass(Class<?> _clazz) throws NoSuchMethodException, SecurityException {
final Method[] ms = new Method[methods.length];
int i = 0;
for(final Method m: methods) {
ms[i] = _clazz.getMethod(m.getName(), m.getParameterTypes());
i++;
}
maps.put(_clazz, ms);
}
public ISomeInterface wrapper(Object _obj) {
final Method[] ms = maps.get(_obj.getClass());
// To be replaced by guava's Preconditions.checkState()
if (ms == null)
throw new NoSuchElementException(String.format("Class %s is unregistered", _obj.getClass().getName()));
return new SomeInterfaceImpl(_obj, ms);
}
private static class SomeInterfaceImpl implements ISomeInterface {
private final Object obj;
private final Method[] ms;
public SomeInterfaceImpl(Object _obj, Method[] _ms) {
ms = _ms;
obj = _obj;
}
#Override
public String getName() {
try {
return (String) ms[0].invoke(obj);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
throw new RuntimeException(e);
}
}
#Override
public void setName(String _name) {
try {
ms[1].invoke(obj, _name);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
throw new RuntimeException(e);
}
}
#Override
public void save() {
try {
ms[2].invoke(obj);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
throw new RuntimeException(e);
}
}
}
}
And test class ReflectTest.java. Notice that classes ReflectTest.Test and ReflectTest.Test2 has the same methods as ISomeInterface but don't implement it, they are completely independent from that interface and from each other.
package org.test2;
import org.test.ISomeInterface;
import org.test1.ReflectCaller;
public class ReflectTest {
private final ReflectCaller rc;
ReflectTest(Class ... _classes) throws NoSuchMethodException, SecurityException {
rc = new ReflectCaller();
for(final Class c: _classes)
rc.inspectClass(c);
}
void callSequence(Object _o) {
// this function demonstrates the sequence of method calls for an object which has "compliant" methods
ISomeInterface tw = rc.wrapper(_o);
tw.setName("boo");
System.out.printf("getName() = %s\n", tw.getName());
tw.save();
}
public static class Test {
public String getName() {
System.out.printf("%s.getName()\n", getClass().getName());
return "boo";
}
public void setName(String _name) {
System.out.printf("%s.setName(%s)\n", getClass().getName(), _name);
}
public void save() {
System.out.printf("%s.save()\n", getClass().getName());
}
}
public static class Test2 {
public String getName() {
System.out.printf("%s.getName()\n", getClass().getName());
return "boo2";
}
public void setName(String _name) {
System.out.printf("%s.setName(%s)\n", getClass().getName(), _name);
}
public void save() {
System.out.printf("%s.save()\n", getClass().getName());
}
}
public static void main(String[] args) {
ReflectTest rt;
try {
rt = new ReflectTest(Test.class, Test2.class);
} catch (NoSuchMethodException | SecurityException e) {
System.out.println(e);
System.exit(2);
return;
}
rt.callSequence(new Test());
rt.callSequence(new Test2());
}
}
I am working on some workflow and it is possible to raise many exceptions in that. I heard that we can keep all those possible exceptions in an Enum (Exception1, Exception2 ...) and use it. How can we do that using Enums in Java?
You can add the classes of exceptions with
enum EnumWithExceptions {
ENUM1(Exception1.class, Exception2.class),
ENUM2(Exception3.class);
private final Class<? extends Exception>[] exceptions;
private EnumWithExceptions(Class<? extends Exception>... exceptions) {
this.exceptions = exceptions;
}
public boolean matches(Exception e) {
for(Class<? extends Exception> e2: exceptions)
if (e2.isInstance(e)) return true;
return false;
}
}
} catch(Exception e){
if (ENUM1.matches(e)){
//do something
} else if(ENUM2.matches(e)) {
//do something
} else {
//do something
}
}
enum Fred {
SAM(AnException.class),
I(AnotherException.class),
AM(YetAnotherException.class)
;
private Throwable t;
Fred(Throwable throwable) {
this.t = throwable;
}
public Throwable getThrowable() {
return t;
}
}
...
throw Fred.SAM.getThrowable();
Why not store the exceptions in an ArrayList? Or if you want to name the index, you could use a HashMap.
import java.util.ArrayList;
import java.util.HashMap;
public final class ExceptionStorage {
private static int exceptionCount = 0;
private static HashMap<String, Exception> indexedExceptions = new HashMap<>();
private static ArrayList<Exception> exceptions = new ArrayList();
public static void addException(Exception e) {
exceptions.add(e);
}
public static void putException(Exception e) {
indexedExceptions.put("Exception" + (++exceptionCount), e);
}
public static ArrayList<Exception> getUnindexedExceptions() {
return this.exceptions;
}
public static HashMap<String, Exception> getIndexedExceptions() {
return this.indexedExceptions;
}
}
Obviously you would have to modify the code to use either ArrayList or HashMap, but I think this would be a better solution than using Enums.
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 {
...
}
}