I got a method that prints out the animals' names.
I now need an error to be printed out if the id is not one of the given ones.
How does it work?
class Methode {
static final int DEER = 0;
static final int BIRD = 1;
static final int COW = 2;
static final int PIG = 3;
public static void main(String[] args) {
printAnimal();
}
public static void printAnimal (int id) {
if (id == DEER) {
System.out.println("Deer");
}
else if (id == BIRD) {
System.out.println("Bird");
}
else if (id == COW) {
System.out.println("COW");
}
else if (id == PIG) {
System.out.println("Pig");
}
}
}
If by error you mean an Exception (otherwise I don't know why you didn't simply printed an "error" message like you did in your else if branches), then you need to create a custom class which extends Exception and throw it in a new else branch. Here is an example:
Exception:
public class NoSuchAnimalException extends Exception {
public NoSuchAnimalException(String message) {
super(message);
}
}
Test:
public static void printAnimal(int id) throws NoSuchAnimalException {
if (id == DEER) {
System.out.println("Deer");
} else if (id == BIRD) {
System.out.println("Bird");
} else if (id == COW) {
System.out.println("COW");
} else if (id == PIG) {
System.out.println("Pig");
} else {
throw new NoSuchAnimalException("No such animal");
}
}
public static void main(String[] args) {
try {
printAnimal(6);
} catch (NoSuchAnimalException e) {
System.out.println(e.getMessage());
}
}
The exception will be thrown in the last else (the id provided in method call doesn't meet the previous requirements) and will be handled in the public static void main() method.
Firstly you call your printAnimal() method without a parameter. That's no good.
Secondly, there are two kinda of exceptions in Java, checked and unchecked. You need to consider which kind you're working with.
Checked means your function must be declared by:
methodName() throws SomeException{
...}
And accordingly a caller MUST catch exceptions.
Unchecked means you can throw the exception without doing this, but other programmers aren't made aware of (and conversely, not forced to handle) any exceptions thrown.
Exceptions should be created, like classes, inheriting the base type of exception appropriate.
Checked exception
class someException extends exception{...}
Unchecked exception
class someException extends RuntimeException{...}
For non custom exceptions they are thrown like so:
The checked exception
throw new Exception ('message');
The unchecked exception
throw new RuntimeException ('message');
Please read the Java doc on exceptions.
Exceptions are an important part of OOP
(This was written on a phone, so there might be a few typos etc.)
Should use enums and switch for this task:
public class Methode {
public enum Animal {
DEER (0),
BIRD (1),
COW (2),
PIG (3);
private final int value;
private static Map valueMap = new HashMap<>();
Animal(int value)
{
this.value = value;
}
static {
for (Animal enumVal : Animal.values()) {
valueMap.put(enumVal.value, enumVal);
}
}
public static Animal valueOf(int animalId) {
return (Animal) valueMap.get(animalId);
}
public int getValue()
{
return value;
}
}
public static void main(String[] args) throws Exception {
printAnimal(1);
}
public static void printAnimal (int id) throws Exception {
Animal animal = Animal.valueOf(id);
if(animal == null) {
throw new Exception("Animal not found"); //better use own exception
} else {
switch (animal) {
case DEER:
System.out.println("Deer");
break;
case BIRD:
System.out.println("Bird");
break;
case COW:
System.out.println("COW");
break;
case PIG:
System.out.println("Pig");
break;
default:
System.out.println(animal.name());
}
}
}
}
Related
Weak in generic, please go easy!
I have some base and derived classes structured as below via generics
public abstract class ProcessingNode<T extends APICommand> extends Node {
}
public class CustomerProcessingNode extends ProcessingNode<CHDAPICommand> {
}
public class MerchantProcessingNode extends ProcessingNode<MHDAPICommand> {
}
public class APICommand {
}
public class CHDAPICommand extends APICommand {
}
public class MHDAPICommand extends APICommand {
}
Now, during server start i would want to pick the right ProcessingNode and cache it as below:
private void cacheProcessingNodeManager() throws ListenerException {
// throws Unexpected Bound error
ProcessingNode<T extends APICommand> processingNodeManager = null;
if (condition1 is true){
// throws "required ProcessingNode<T> but found CustomerProcessingNode"
processingNodeManager = new CustomerProcessingNode();
}
else if (condition2 is true){
// throws "required ProcessingNode<T> but found MerchantProcessingNode"
processingNodeManager = new MerchantProcessingNode();
} else {
// some exception
}
// cache processingNodeManager
}
but i get 2 error as highlighted in comments above.
What would be the right way to create specific objects of ProcessingNode?
You can't decide T has to be CHDAPICommand or MHDAPICommand inside the method cacheProcessingNodeManager(). You can only decide T when declaring class and method.
You can create specific objects of ProcessingNode in two ways.
use Wild Card Generic
public void cacheProcessingNodeManager() throws Exception {
ProcessingNode<? extends APICommand> processingNodeManager = null;
if (condition1 is true){
processingNodeManager = new CustomerProcessingNode();
} else if (condition2 is true){
processingNodeManager = new MerchantProcessingNode();
} else {
// some exception
}
}
declaring Generic with method and use upcasting
public <T extends APICommand>void cacheProcessingNodeManager() throws Exception {
ProcessingNode<T> processingNodeManager = null;
if (condition1 is true){
processingNodeManager = (ProcessingNode<T>) new CustomerProcessingNode();
} else if (condition2 is true) {
processingNodeManager = (ProcessingNode<T>) new MerchantProcessingNode();
} else {
// some exception
}
}
My program parses WebAssembly instructions and makes decisions based on the context of the current instruction. So, the MWE for my algorithm looks like this:
public class Main {
public interface Context {
String name();
}
static class M implements Context {
public String name() {
return "Context M: ";
}
}
static class N implements Context {
public String name() {
return "Context N: ";
}
}
public interface Instruction {
int getId();
String run();
}
static class A implements Instruction {
public int getId() {
return 0;
}
public String run() {
return "The work of A";
}
}
static class B implements Instruction {
public int getId() {
return 1;
}
public String run() {
return "The work of B";
}
}
static void work(Context context, Instruction instruction) {
switch (instruction.getId()) {
case 0:
workOnId0(context, (A) instruction);
break;
case 1:
workOnId1(context, (B) instruction);
break;
default:
throw new RuntimeException("Failed to recognize instruction");
}
}
static void workOnId0(Context context, A instruction) {
System.out.println(context.name() + instruction.run());
}
static void workOnId1(Context context, B instruction) {
System.out.println(context.name() + instruction.run());
}
static void workOnId1(N context, B instruction) {
System.out.println("This is corner case logic for this context!");
}
public static void main(String[] args) {
N context = new N();
B instruction = new B();
work(context, instruction);
}
}
As you can see from above, when my instruction is B, then the ordinary work should happen in workOnId1, but in case my context is specifically N, I would like some special work done, which is represented by a different overload of workOnId1.
Unfortunately, the special overload never gets called. How can I make the overload resolution work?
workOnId1(Context context, B instruction) will always be called, because you have a Context object.
You are going to need to differentiate method calls by casting to N. If this doesn't work well within your model, since I'm guessing this is only a small example, you may need to rethink your overall design. A simple solution would be:
if(context instanceof N) {
workOnId1((N)context, (B)instruction);
} else {
workOnId1(context, (B) instruction);
}
you can change one line under case:1 as below to achieve your target
switch (instruction.getId()) {
case 0:
workOnId0(context, (A) instruction);
break;
case 1:
workOnId1((context instanceof N)? (N)context :context, (B) instruction); break;
default:
throw new RuntimeException("Failed to recognize instruction");
}
Hey StackOverflow Community,
I am trying to write code that throws and catches multiple Exceptions that I made.
What might be the problem?
I want to get this output:
Doing risky
Boi
Fooi
Fooi
Fooi
FINAAAL WIN
The main class looks like this:
public class Dorisk {
public static void main(String[] args) {
Dorisk dora = new Dorisk();
try {
dora.Dorisky(1);
}catch(BoinkException bo){
System.out.println("Boi");
}catch(FooException fo){
System.out.println("Fooi");
}catch(BazException ba){
System.out.println("Baaai");
}finally{
System.out.println("FINAAAL WIN");
}
}
public void Dorisky(int x)throws BazException{
while( x < 5 ){
System.out.println("Doing risky");
if(x ==1){
throw new BoinkException();
}
if(x ==2){
throw new BiffException();
}
if(x ==3){
throw new BarException();
}
if(x ==4){
throw new FooException();
}
x++;
}
}
}
And the Exceptions are :
public class BazException extends Exception{
public BazException(){
System.out.println("Baz baja");
}
}
public class FooException extends BazException{
public FooException(){
System.out.println("Foo baja");
}
}
public class BarException extends FooException{
public BarException(){
System.out.println("Bar baja");
}
}
public class BiffException extends FooException{
public BiffException(){
System.out.println("Biff baja");
}
}
public class BoinkException extends BiffException{
public BoinkException(){
System.out.println("Boink baja");
}
}
BUT what I get is:
Doing risky
Baz baja
Foo baja
Biff baja
Boink baja
Boi
FINAAAL WIN
What tells me that only the first Exception in the doRisky method gets thrown, but why?
Thank you for the answers!
Edit: I got it now! The first thrown Exception printed all the other messages, because they were declared in the constructor of the Exception superclasses, and they have to be constructed, so the subclass can run.
Your Dorisky Method throws the exception when x = 1,
means Dorisky method return with BoinkException exception to caller method.
if(x ==1){
throw new BoinkException();
}
First, Why you want to return multiple exceptions?
It is not the right way to design. BTW... I implemented for your understanding.
Here, I created CustomException for each throw and ExceptionList that holds the list of throwable exception.
import java.util.*;
import java.lang.*;
import java.io.*;
/* Name of the class has to be "Main" only if the class is public. */
class Ideone
{
private static ArrayList<Exception> ex = new ArrayList<Exception>();
private static class CustomException extends Exception {
int i;
public CustomException(int i) {
this.i = i;
}
public String toString() {
return "Exception: " + i;
}
}
private static class ExceptionList extends Exception {
ArrayList<Exception> ex = new ArrayList<Exception>();
public ExceptionList(ArrayList<Exception> ex) {
this.ex = ex;
}
public ArrayList<Exception> getEx() {
return ex;
}
}
public static List<Exception> process() throws Exception {
int i = 0;
while(i < 5) {
if(i == 1) {
ex.add (new CustomException(i));
} else if(i==2) {
ex.add (new CustomException(i));
} else if(i==3) {
ex.add (new CustomException(i));
}
i++;
}
if(ex.size() > 0) {
throw new ExceptionList(ex);
} else {
return null;
}
}
public static void main (String[] args) throws java.lang.Exception
{
try {
new Ideone().process();
} catch(ExceptionList ex) {
for(Exception ei : ex.getEx()) {
System.out.println(ei.toString());
}
}
}
}
Output
Exception: 1
Exception: 2
Exception: 3
How to safe implement the use of valueOf in case i get a String different than the supported on the enum ACTION. I mean is possible to force to ACTION.valueOf(valueToCompare) to get a valid value even when happens that valueToCompare is not a valid enum member
I get an expected execution when valueToCompare is "CRY" or "CRYALOT" or "cryalot" etc.
And i get java.lang.IllegalArgumentException on cases like in the code.
public enum ACTION{
CRY,
CRYALOT;
}
public static void main(String[] args) {
String valueTocompare = "posible not expected value".toUpperCase();
switch (ACTION.valueOf(valueToCompare)) {
case CRY:
System.out.println("Cry");
break;
case CRYALOT:
System.out.println("Cry a lot");
break;
default:
System.out.println("catch posible not expected value");
break;
}
}
EDIT & used SOLUTION:
I solved this by using a try-catch as #Peter Lawrey suggested:
public enum ACTION{
CRY,
CRYALOT,
NOTVALID;
}
public static void main(String[] args) {
String valueToCompare = "NOTVALID";
ACTION action;
try {
valueToCompare= "variable posible not expected value".toUpperCase();
action = ACTION.valueOf(valueToCompare);
} catch(IllegalArgumentException e){
System.out.println("Handled glitch on the Matrix");
action = ACTION.NOTVALID;
}
switch (action) {
case CRY:
System.out.println("Cry");
break;
case CRYALOT:
System.out.println("Cry a lot");
break;
default:
System.out.println("catch posible not expected value");
break;
}
System.out.println("We continue normal execution on main thread...");
}
You need to catch the IllegalArgumentException
try {
switch (ACTION.valueOf(valueToCompare)) {
}
} catch (IllegalArgumentException iae) {
// unknown
}
Or you can create your own function which does this.
public static <E extends Enum<E>> E valueOf(E defaultValue, String s) {
try {
return Enum.valueOf(defaultValue.getDeclaringClass(), s);
} catch (Exception e) {
return defaultValue;
}
}
Note: switch(null) throws a NullPointerException rather than branching to default:
Using exceptions for flow control is considered as a bad practice.
String valueToCompare = value.toUpperCase();
ACTION action = Arrays.stream(ACTION.values())
.filter(a -> a.name().equals(valueToCompare)).findFirst().orElse(ACTION.NOTVALID);
the problem here is this line:
ACTION.valueOf(valueToCompare) - you are trying to run valueOf on valueToCompare, and its erroring out since the value isn't an enum in ACTION. It's not even making the switch statement to print out the default msg.
Have a look at the changes I've done, you'll notice a few things, the main one being actionToCompare...
enum Action {
CRY,
CRYALOT,
EXAMPLE
}
public static void main(String[] args) {
Action actionToCompare = Action.EXAMPLE;
switch (actionToCompare) {
case CRY:
System.out.println("Cry");
break;
case CRYALOT:
System.out.println("Cry a lot");
break;
default:
System.out.println("catch posible not expected value");
break;
}
}
if you insist on using a String over converting it to the enum Action, wrap it in a try...catch statement so if an invalid string is passed in it can handle the error.
You can always build yourself a reverse-lookup.
enum Action {
CRY,
CRYALOT,
EXAMPLE;
// Lookup map for actions in string form.
static Map<String,Action> lookup = Arrays.stream(values()).collect(Collectors.toMap(
// Key is name in lowercase.
a -> a.name().toLowerCase(),
// Value is the Action.
a -> a));
public static Action lookup(String name) {
return lookup.get(name.toLowerCase());
}
}
public void test() throws Exception {
System.out.println(Action.lookup("cry"));
System.out.println(Action.lookup("CryAlot"));
}
A solution that does not involve exceptions in the control flow and enables mapping the enum name or the action name to the action with a default behavior in case there is no mapping entry:
public enum CryActions {
CRY_A_LITTLE("Cry a little", CryALittleActionHandler::new), CRY_A_LOT("Cry a lot", CryALotActionHandler::new), DEFAULT("Default", DefaultCryActionHandler::new);
private String actionName;
private Supplier<CryActionHandler> supplier;
private CryActions(String actionName, Supplier<CryActionHandler> supplier) {
this.actionName = actionName;
this.supplier = supplier;
PossibleCryActions.byEnumName.put(name(), this);
PossibleCryActions.byActionName.put(actionName, this);
}
public void handleAction() {
supplier.get().handleAction();
}
public String getActionName() {
return actionName;
}
public static CryActions fromEnumName(String enumName) {
return PossibleCryActions.byEnumName.computeIfAbsent(enumName, x -> DEFAULT);
}
public static CryActions fromActionName(String actionName) {
return PossibleCryActions.byActionName.computeIfAbsent(actionName, x -> DEFAULT);
}
private static class PossibleCryActions {
private static Map<String, CryActions> byEnumName = new HashMap<>();
private static Map<String, CryActions> byActionName = new HashMap<>();
}
}
public interface CryActionHandler {
void handleAction();
}
public class CryALittleActionHandler implements CryActionHandler {
#Override
public void handleAction() {
System.out.println("Just crying a little...");
}
}
public class CryALotActionHandler implements CryActionHandler {
#Override
public void handleAction() {
System.out.println("Crying a river...");
}
}
public class DefaultCryActionHandler implements CryActionHandler {
#Override
public void handleAction() {
System.out.println("Just crying as default behavior...");
}
}
public class Main {
public static void main(String[] args) {
CryActions.fromEnumName("CRY_A_LITTLE").handleAction();
CryActions.fromEnumName("CRY_A_LOT").handleAction();
CryActions.fromEnumName("CRY_UNEXPECTEDLY").handleAction();
CryActions.fromActionName("Cry a little").handleAction();
CryActions.fromActionName("Cry a lot").handleAction();
CryActions.fromActionName("Cry unexpectedly").handleAction();
}
}
Kotlin version:
inline fun <reified T : Enum<T>> safeValueOf(name: String, defaultValue: T): T =
try {
java.lang.Enum.valueOf(T::class.java, name) ?: defaultValue
} catch(e: IllegalArgumentException) {
defaultValue
}
I have a function which calls another function in a different class which throws an exception based on the paraameter provided. I want
public class A {
public int f(int p){
{
B obj = new B();
obj.g(p);
}
}
public class B {
public int g(int p)
{
// throws an exception for this value of p
}
}
Is it possible that I can catch the exception in class A itself and handle it ? I can't change the implementation of class B.
Yeah just use a try-catch statement.
public class A {
public int f(int p){
{
B obj = new B();
try {
obj.g(p);
} catch ( /* the exception */ ) {
// handle the exception
}
}
}
public class B {
public int g(int p)
{
// throws an exception for this value of p
}
}