How to validate the state of a java enum? - java

I would like to be able to validate the state of the enum to make sure there are no duplicate codes. For example consider the enum below.
public enum UniqueCodes {
A(1), B(2), C(3), D(1);
private final int value;
static {
UniqueCodes[] values = UniqueCodes.values();
Map<Integer, Boolean> map = new HashMap<>();
for (UniqueCodes code : values) {
if (map.get(code.value) == null) {
map.put(code.value, true);
} else {
String msg = String.format(
"%s enum contains a non unique code %s",
UniqueCodes.class.getName(), code.value);
System.err.println(msg);
try {
System.exit(-1);
} catch(SecurityException e) {
System.err.println("Really Bad things are going to happen to the application");
// what can I do here to crash the JVM
}
}
}
}
private UniqueCodes(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
Imagine the above enum with 100+ codes assigned and you want to make sure that no enum definition
contains a duplicate value. If a duplicate value is detected I want to crash the JVM but that is not that is easy to do. Throwing an exception is not effective because a catch(Throwable e) will catch everything.
public class Main {
public static void main(String[] args) {
try {
System.out.println(UniqueCodes.A);
} catch(Throwable e) {
System.out.println("Invalid Enum exception caught");
}
}
}
I can write a unit test to prove that the enum definition is good and there are no duplicate codes. But is there a way to kind of make it self testing and fool proof so that things don't run if the enum does not have unique codes?

A couple of points:
It is simpler to use a set than a map for this.
Throwing an exception out of a class's static block will be effective because it will block the loading of the class. Even if you deliberately catch and ignore the first error with a catch (Throwable t), any later code which tries to make any use of the "invalid" enum will spontaneously throw a java.lang.NoClassDefFoundError.
I'd write the validation code as follows:
static {
Set<Integer> set = new HashSet<>();
for (UniqueCodes code : values()) {
if (!set.add(code.value)) {
throw new RuntimeException(String.format(
"%s enum contains a non unique code %s",
UniqueCodes.class.getName(), code.value));
}
}
}
P.S. If you don't need any particular value for the unique codes, you should know that Enum.ordinal() exists, which returns the zero-based index of the constant in the order it was defined.

It would be simplest to have the constructor check that the value is unique, like this:
A(1), B(2), C(3), D(1);
// Not initialized until after instances
private static Set<Integer> set = new HashSet<Integer>();
private final int value;
private UniqueCodes(int value) {
// throws NPE
if (!set.add(value))
throw new IllegalArgumentException("Duplicate value: " + value);
this.value = value;
}
but the challenge with enums is that static fields must appear after the instances, and so are not initialized until after all constructors are executed - too late, and you get a NPE when you go to use the set.
Fortunately, there's a work around!
You can use the Initialization-on-demand holder idiom to give you an initialized set before the instances are initialized:
public enum UniqueCodes {
A(1), B(2), C(3), D(1);
private static class Holder {
static Set<Integer> set = new HashSet<Integer>();
}
private final int value;
private UniqueCodes(int value) {
if (!Holder.set.add(value))
throw new IllegalArgumentException("Duplicate value: " + value);
this.value = value;
}
public int getValue() {
return value;
}
}
The reason this works is thanks to the class loader contract, which must initialize all static fields before the class can be used, and the class is loaded when first used. The Holder class is first used in the constructor, and at that point the class loader initializes the set.
To see what happens when you access the enum, see this link.

I'm not sure this is even worth doing for enums like your example. Since you are hardcoding the enum yourself, can't you as the coder just make sure you aren't hardcoding the enum incorrectly?

Related

How to get value by Java enum class name and field name

How to get value by Java enum class name and field name?
The sample code is as follows, but I don't know how to pass the enum class as a parameter.
public enum ErrorCodes1{
OK(0),
NOT_EXIST_USER(1),
FAIL_TO_SEND_MAIL(2),
...
}
public enum ErrorCodes2{
OK(0),
NOT_EXIST_USER(1),
FAIL_TO_SEND_MESSA(2),
...
}
public void foo1()
{
foo2(ErrorCodes1.class, "NOT_EXIST_USER");
foo2(ErrorCodes2.class, "NOT_EXIST_USER");
}
public void foo2(Enum EnumClass, String EnumText)
{
int code = xxxx; //I want to get code(1) via EnumText and EnumClass, but I don't know how to do it.
}
You can use the type Class as a param of your function foo2
public static void foo2(Class<?> enumClass, String enumText) {
int code = -1; // I want to get code(1) via EnumText and EnumClass, but I don't know how to do
// it.
switch (enumClass.getCanonicalName()) {
case "ErrorCodes2": {
ErrorCodes1 errorCode = ErrorCodes1.valueOf(enumText);
code = errorCode.ordinal();
}
case "ErrorCodes1": {
ErrorCodes1 errorCode = ErrorCodes1.valueOf(enumText);
code = errorCode.ordinal();
}
}
System.out.println(code);
}
After that, you can use valueOf to instantiate your enum from a string that contains the enum value. I don't think this is the best solution but its works.
PS: The param of a function begins with a lowercase letter.
Option A, simple: check for the type explicitly.
int code;
if (enumClass instanceof ErrorCodes1) {
code = ((ErrorCodes1) enumClass).valueOf(enumText).ordinal();
} else if (enumClass instanceof ErrorCodes2)
// repeat
This implies you can pass an error object itself, not necessarily its class. Unfortunately, switch does not work with Class type.
Option B, probably overkill: use Reflection.
public void foo2(Class<?> enumClass, String enumText) {
try{
Object resultingEnum = enumClass.getMethod("valueOf", String.class).invoke(null, enumText);
int code = (Integer) resultingEnum.getClass().getMethod("ordinal").invoke(resultingEnum);
// ...
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e ) {
// ignore: enumClass is not an expected class
}
}
This will suit you in case you have an unlimited number of ErrorCode enums, though it is a barely plausible situation.

Safe get value from chain without NPE

Does anyone know any solution to safely get value without NPE and without a lot of if statements?
For example, we have: userInfo.getAddressInfo().getCityName(),
how to get cityName without null-checks?
Sometimes, for my pet projects I use something like that:
public static <T> String safeGetValue(Supplier<String> supplier) {
try {
return supplier.get();
} catch (NullPointerException e) {
e.printStackTrace();
}
return "";
}
Maybe exists better way to do this.
Full example:
import java.util.function.Supplier;
public class ExampleClass {
public static void main(String[] args) {
UserInfoResponse userInfo = new UserInfoResponse();
String value = safeGetValue(() -> userInfo.getAddressInfo().getCityName());
System.out.println(value);
}
public static <T> String safeGetValue(Supplier<String> supplier) {
try {
return supplier.get();
} catch (NullPointerException e) {
e.printStackTrace();
}
return "";
}
public static <T> String safeGetValue(Supplier<String> supplier, String defaultValue) {
try {
return supplier.get();
} catch (NullPointerException e) {
e.printStackTrace();
}
return defaultValue;
}
public static <T> String safeGetValue(Supplier<String> supplier, Runnable runnable) {
try {
return supplier.get();
} catch (NullPointerException e) {
runnable.run();
}
return "";
}
public static <T> String safeGetValue(Supplier<String> supplier, Runnable runnable, String defaultValue) {
try {
return supplier.get();
} catch (NullPointerException e) {
runnable.run();
}
return defaultValue;
}
}
class UserInfoResponse {
private String firstName;
private UserAddressInfo addressInfo;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public UserAddressInfo getAddressInfo() {
return addressInfo;
}
public void setAddressInfo(UserAddressInfo addressInfo) {
this.addressInfo = addressInfo;
}
}
class UserAddressInfo {
private String cityName;
public String getCityName() {
return cityName;
}
public void setCityName(String cityName) {
this.cityName = cityName;
}
}
I'm looking for a solution without if statements.
Ternary statement can't be a good solution too.
Unfortunately, if tests and conditional expressions are the only alternatives to catching NPEs. (But they are better alternatives!)
To me, the real problem is that the nulls are there in the first place. A better idea is to modify the design so that nulls are not returned. If they are not returned by getters, then you don't have to deal with them.
Here are some ways to design your APIs to not return null.
Make it impossible to create domain objects with null field values:
Constructors and setters should check that their arguments are not null, and thrown an exception (e.g. NPE) when called with bogus null arguments.
Fields could be default initialized with non-null values.
Have the getters return non-null values when field values are null. (But see below!)
Have the getters throw an exception when the user gets a field which should not be null has a null value.
Use the Null Object pattern. Create an special instance of each of your domain objects that represents "no object". Ideally, a Null Object should be immutable ... or should throw an exception if you attempt to modify it by accident.
Use Optional<ReferenceType>.
For builtin types / common types:
use "" instead of null for strings
use a zero length array instead of null for arrays
use (immutable) empty collection objects instead of null for collection types
avoid the primitive wrapper types: use the primitive types that cannot be null.
The other way to look at this is that if your API is specified so that a getter shouldn't return a null, then if it does return a null that is a bug. So, if you then write code to turn the nulls into something else (e.g. empty strings) to avoid the pesky NPEs, what you actually doing is hiding the bugs. A better idea is to let the NPE happen, log it, and then crash the application. (Or return a "500 Internal Error" response.)
Fixing a bug is better than hiding a bug.
But (I hear you ask) "What about reliability? It is embarrassing if my code crashes with NPEs!"
Well yes, but an NPE is better than a null workaround that gives incorrect answers to your users ... or writes bad data into your database.
And the conventional way to avoid bugs (e.g. NPEs) showing up in production is extensive automated testing. More / better unit tests. More / better system tests. Beta test releases, pre-production servers, etc.
Using Optional<T> chain you can write following
UserInfoResponse userInfo = new UserInfoResponse();
String value = Optional.ofNullable(userInfo.getAddressInfo())
.map(UserAddressInfo::getCityName)
.orElse(null);
or
String value = Optional.ofNullable(userInfo)
.map(UserInfoResponse::getAddressInfo)
.map(UserAddressInfo::getCityName)
.orElse(null);
or
String value = Optional.ofNullable(userInfo)
.map(ui -> ui.getAddressInfo())
.map(uai -> uai.getCityName())
.orElse(null);

Use the command line to make new objects

In my program, the user needs to input what type of players the game will have. The players are "human", "good" (for a good AI), "bad" (for a bad AI) and "random" (for a random AI). Each of these players have their own class that extend one abstract class called PlayerType.
My struggle is mapping a String to the object so I can A) create a new object using the String as sort of a key and B) get the related String from an object of its subclass
Ultimately, I just want the implicit String to only appear once in the code so I can change it later if needed without refactoring.
I've tried using just a plain HashMap, but that seems clunky with searching the keys via the values. Also, I'm guessing that I'll have to use the getInstance() method of Class, which is a little less clunky, which is okay if it's the only way.
What I would do is create an enum which essentially functions as a factory for the given type.
public enum PlayerTypes {
GOOD {
#Override
protected PlayerType newPlayer() {
return new GoodPlayer();
}
},
BAD {
#Override
protected PlayerType newPlayer() {
return new BadPlayer();
}
},
RANDOM {
#Override
protected PlayerType newPlayer() {
return new RandomPlayer();
}
};
protected abstract PlayerType newPlayer();
public static PlayerType create(String input) {
for(PlayerTypes player : PlayerTypes.values()) {
if(player.name().equalsIgnoreCase(input)) {
return player.newPlayer();
}
}
throw new IllegalArgumentException("Invalid player type [" + input + "]");
}
)
Because then you can just call it like so:
String input = getInput();
PlayerTypes.create(input);
Of course, you'll get an IllegalArgumentException which you should probably handle by trying to get the input again.
EDIT: Apparently in this particular case, you can replace that loop with just merely
return PlayerTypes.valueOf(input).newPlayer();
And it'll do the same thing. I tend to match for additional constructor parameters in the enum, so I didn't think of using valueOf(), but it's definitely cleaner.
EDIT2: Only way to get that information back is to define an abstract method in your PlayerType class that returns the PlayerTypes enum for that given type.
public class PlayerType {
public abstract PlayerTypes getType();
}
public class GoodPlayer extends PlayerType {
#Override
public PlayerTypes getType() {
return PlayerTypes.GOOD;
}
}
I like the answer provided by Epic but I don't find maps to be clunky. So it's possible to keep a map and get the constructor call directly.
Map<String, Supplier<PlayerType> map = new HashMap<>();
map.put("human", Human::new);
Human h = map.get("human").get();
The two main options I can think of:
Using Class.newInstance(), as you mentioned (not sure if you had this exact way in mind):
// Set up your map
Map<String, Class> classes = new HashMap<String, Class>();
classes.put("int", Integer.class);
classes.put("string", String.class);
// Get your data
Object s = classes.get("string").newInstance();
You could use Class.getDeclaredConstructor.newInstance if you want to use a constructor with arguments (example).
Another option is using switch:
Object getObject(String identifier) {
switch (identifier) {
case "string": return new String();
case "int": return new Integer(4);
}
return null; // or throw an exception or return a default object
}
One potential solution:
public class ForFunFactory {
private ForFunFactory() {
}
public static AThing getTheAppropriateThing(final String thingIdentifier) {
switch (thingIdentifier) {
case ThingImplApple.id:
return new ThingImplApple();
case ThingImplBanana.id:
return new ThingImplBanana();
default:
throw new RuntimeException("AThing with identifier "
+ thingIdentifier + " not found.");
}
}
}
public interface AThing {
void doStuff();
}
class ThingImplApple implements AThing {
static final String id = "Apple";
#Override
public void doStuff() {
System.out.println("I'm an Apple.");
}
}
class ThingImplBanana implements AThing {
static final String id = "Banana";
#Override
public void doStuff() {
System.out.println("I'm a Banana.");
}
}

Make a Java class generic, but only for two or three types

(I was astonished not to be able to find this question already on stackoverflow, which I can only put down to poor googling on my part, by all means point out the duplicate...)
Here is a toy class that returns the reverse of what you put into it. Currently it works on integers, but would require only very minor changes to work for String.
public class Mirror {
int value;
public int get() {
return reverse(value);
}
private int reverse(int value2) {
String valueString = value + "";
String newString = reverse(valueString);
return Integer.parseInt(newString);
}
private String reverse(String valueString) {
String newString = "";
for (char c : valueString.toCharArray()) {
newString = c + newString;
}
return newString;
}
public void set(int value) {
this.value = value;
}
}
What I'd like to do is make the class generic, but only for, say, two or three possible types. So what I want to write is:
public class Mirror<X, where X is one of Integer, String, or MagicValue {
X value
public X get(){
[...]
What's the correct syntax? My Google-fu is failing me... :(
EDIT: it appears there isn't a correct syntax and it can't appear to be done, so my main question is: why? this seems like the sort of thing that people might want to do before they made the class truly generic...
EDIT EDIT: Managed to work out the why with some labmates today, so added the relevant why answer below.
Unfortunately java does not provide such functionality directly. However I can suggest you the following work around:
Create parametrized class Mirror with private constructor and 3 static factory methods that create instance of Mirror with specific parameter:
public class Mirror<T> {
private T value
private Mirror(T value) {
this.value = value;
}
public static Mirror<Integer> integerMirror(Integer value) {
return new Mirror(value);
}
public static Mirror<String> stringMirror(String value) {
return new Mirror(value);
}
public static Mirror<MagicValue> magicMirror(MagicValue value) {
return new Mirror(value);
}
}
EDIT
Obviously you can (and probably should) separate the class Mirror from its creating, e.g. put the factory methods to separate class MirrorFactory. In this case the constructor should become package protected.
If you want to support large yet limited number of classes you can implement only one generic factory method
public static <T> Mirror<T> createMirror(T value) {
checkTypeSupported(value);
return new Mirror(value);
}
Method checkTypeSupported(value); may use some kind of metadatat (e.g. properties, JSON etc file) to get supported types. In this case however you will not enjoy the compile time validation.
Other solution is to require that all supported types extend certain base class or implement interface:
public class Mirror<T extends MyInterface> {}
But this solution seems does not match your requirements since you need Integer, String and MagicValue.
Various ways to do what you need...Here is another option. No getter or setter.
One instance of Mirror for each type to be handled. One reverse() method.
Tweak as necessary. Add error checking/handling.
public class Mirror<T> {
public T reverse(final T value) {
T result = null;
while (true) {
if (value instanceof String) {
System.out.println("Do for String");
result = value;
break;
}
if (value instanceof Integer) {
System.out.println("Do for Integer");
result = value;
break;
}
if (value instanceof JFrame) {
System.out.println("Do for JFrame");
result = value;
break;
}
throw new RuntimeException("ProgramCheck: Missing handler for type " + value.getClass().getSimpleName());
}
return result;
}
Tester:
final Mirror<String> testerString = new Mirror<>();
testerString.reverse("string");
final Mirror<Integer> testerInteger = new Mirror<>();
testerInteger.reverse(41);
testerInteger.reverse(42);
testerInteger.reverse(43);
final Mirror<JFrame> testerJFrame = new Mirror<>();
testerJFrame.reverse(new JFrame());
Results:
Do for String
Do for Integer
Do for Integer
Do for Integer
Do for JFrame
An alternative would be to just accept the fact that you have no control over the type hierarchy of String/Integer and create an interface to give a common type for the classes you do have control over
public int reverse(int value) {
return Integer.valueOf(new StringBuilder(value + "").reverse()
.toString());
}
public String reverse(String value) {
return new StringBuilder(value + "").reverse().toString();
}
public <T extends Reversible> T reverse(T value) {
value.reverse();
return value;
}
public interface Reversible {
public void reverse();
}
And if you only want one instance of the Mirror class...use a generic method.
public class Mirror {
public <T> T reverse(final T value) {
T result = null;
while (true) {
if (value instanceof String) {
System.out.println("Do for String");
result = value;
break;
}
if (value instanceof Integer) {
System.out.println("Do for Integer");
result = value;
break;
}
if (value instanceof JFrame) {
System.out.println("Do for JFrame");
result = value;
break;
}
throw new RuntimeException("ProgramCheck: Missing handler for type " + value.getClass().getSimpleName());
}
return result;
}
tester:
final Mirror tester = new Mirror();
String s = tester.reverse("string");
Integer i41 = tester.reverse(41);
Integer i42 = tester.reverse(42);
Integer i43 = tester.reverse(43);
JFrame j = tester.reverse(new JFrame());
results:
Do for String
Do for Integer
Do for Integer
Do for Integer
Do for JFrame
You can't bound a generic parameter to range of values. You could however restrict it programatically:
public abstract class AbstractMirror<T> {
T value;
protected AbstractMirror(Class<T> clazz) {
if (clazz != Integer.class && clazz != String.class && clazz != MagicValue.class)
throw new IllegalArgumentException();
}
public abstract T get();
protected abstract T reverse(T value);
}
You can use so-called "witness" types to make the compiler do what you want.
public interface Reversible< T > {
public static final class IntReversible implements Reversible< Integer > {}
public static final class StringReversible implements Reversible< String > {}
public static final class MagicReversible implements Reversible< MagicValue > {}
}
public abstract class Mirror< T, R extends Reversible< T > > {
// ...
}
public class IntMirror extends Mirror< Integer, IntReversible > {
// ...
}
However, the reason your example doesn't make any sense is because you gain virtually nothing from using a generic in this context. What possible algorithm will reverse an integer or a string or a MagicValue without resorting to awful run-time type-checking and casting? The code will be all three reverse algorithms, wrapped with a hideous if-ladder.
So here is the why (worked it out at work)
Generics are always from a subclass, although it looks like
Public class Thing<T> {}
will allow any type in there, really what it's saying is that it will allow any subtype of Object. I.e.
Public class Thing<T extends Object> {}
This is effectively working as inheritance, and indeed, the Oracle Website shows us this happening when the syntactic sugar is removed:
In the following example, the generic Node class uses a bounded type
parameter:
public class Node<T extends Comparable<T>> {
private T data;
private Node<T> next;
public Node(T data, Node<T> next) {
this.data = data;
this.next = next;
}
public T getData() { return data; }
// ...
}
The Java compiler replaces the bounded type parameter T with the first
bound class, Comparable:
public class Node {
private Comparable data;
private Node next;
public Node(Comparable data, Node next) {
this.data = data;
this.next = next;
}
public Comparable getData() { return data; }
// ...
}
...and so the answer turns out that the reason you can't limit the types in this way is because it effectively turns into multiple Inheritance, which is nasty, and which I'm happy to avoid....

How to Load Values for Java Enum Elements from A File

I have a Java Enum:
public enum CodeType {
BRONZE("00001BP", "BAP"),
SILVER("00002SL", "SAP"),
GOLD("00003GL", "GAP"),
MOBILE("00004MB", "TCM"),
SOCIAL("00005SM", "ASM"),
WEB_PRESENCE("00006WP", "GLO"),
EMAIL_MARKETING("00007EM", "PEM"),
CUSTOM_DIAMOND("00008CD", "PCS"),
CONSUMER_PORTAL("00009CP", "CPS");
private String code;
private String key;
CodeType(String code, String key) {
this.code = code;
this.key = key;
}
...
}
As you see, I have nine elements and each has two values. My question is How can I load values for those elements from a file like properties or xml? I mean:
BRONZE(isLoadedFromFile, isLoadedFromFile),
...
CONSUMER_PORTAL(isLoadedFromFile, isLoadedFromFile);
Thanks so much.
Try something like this..
public enum EnumTest {
BRONZE, SILVER;
public String getProperty(String keyOrCode) {
Properties prop = new Properties();
try {
prop.load(new FileInputStream("E:\\EnumMapper.properties"));
} catch (Exception e) {
e.printStackTrace();
}
return prop.getProperty(this.name() + "." + keyOrCode);
}
public String getCode() {
return getProperty("CODE");
}
public String getKey() {
return getProperty("KEY");
}
public static void main(String[] args) {
System.out.println(EnumTest.BRONZE.getCode());
System.out.println(EnumTest.BRONZE.getKey());
}
}
where the EnumMapper.properties contains
BRONZE.CODE=00001BP
BRONZE.KEY=BAP
SILVER.CODE=00002SL
SILVER.KEY=SAP
Just wanted to share some possibilities..
If I understand your question correctly, you would need to do so in the constructor (which is misnamed in your example).
The hard-coded defaults you show would serve as the defaults, but in the constructor you would check/load some properties file and override them.
In general though, this smells of an odd/bad design. You would need to hard-code that properties file / resource in the enum. You're also dynamically loading what is meant to be something that represents a constant value.
It seems like really you should be using your own class to hold these values.
One option is to generate a static map based on the resource file within the enum class, mapping from enum values to the data in the file. The map can then be used for the getter.
For instance with a resource file formatted like this:
A=red
B=blue
C=yellow
it can be initialized like this:
public enum MyEnum {
A, B, C;
public String getFoo() {
return enumFooValuesFromResourceFile.get(this);
}
private static final Map<MyEnum, String> enumFooValuesFromResourceFile;
static {
Map<MyEnum, String> temp = Collections.emptyMap();
try {
String data = new String(MyEnum.class.getResourceAsStream("resourcepath").readAllBytes());
temp = Arrays.stream(data.split("\n"))
.map(line -> line.split("="))
.collect(Collectors.<String[], MyEnum, String>toMap(
key_val -> MyEnum.valueOf(key_val[0]),
key_val -> key_val[1]));
} catch (IOException iE) {
// helpful message.
} finally { enumFooValuesFromResourceFile = temp; }
}
}
A nicer option, I think, is to use a static String for the resource file data, and store the values directly on the enum items during initialization. During enum initialization, you cannot access a static property of the enum, so it must either be outside it, or in an inner class using the Initialization-on-demand holder idiom (credit to) which is neat, because it's lazy and not loaded if the enum is never accessed.
(I found I can set the (non-final) String to null at the end of the enum declaration, freeing that memory.)
public enum MyEnum {
A, B, C;
public String getFoo() { return foo; }
final String foo;
MyEnum() {
foo = getFooValue();
}
private String getFooValue() {
return Arrays.stream(ResourceHolder.resourceFileString.split("\n"))
.filter(str -> str.startsWith(this.name() + '='))
.findFirst()
.map(str -> str.replaceAll("^" + this.name() + '=', ""))
.orElseThrow(() ->
new IllegalArgumentException(this.name() + " not found in resourcefile."));
}
// Release resources (string) from memory after enum initialization.
static {ResourceHolder.resourceFileString = null;}
private static class ResourceHolder {
// Lazily initialized if/when MyEnum is accessed.
// Cleared after initialization.
private static String resourceFileString;
static {
try {
InputStream lResource =
Objects.requireNonNull(MyEnum.class.getResourceAsStream("resourcepath"));
resourceFileString = new String(lResource.readAllBytes());
} catch (IOException iE) {
// helpful message.
iE.printStackTrace();
}
}
}
}

Categories

Resources