This question already has answers here:
What causes javac to issue the "uses unchecked or unsafe operations" warning
(12 answers)
Closed 3 years ago.
I want to make a generic container class that can contain one object of some other class. I thought this might be a reasonable approach:
class Container <T> {
private T thing;
public void Store(T obj) {
thing = obj;
}
public T ReturnIt() {
return thing;
}
}
When I try this together with let's say a Book class, I get the following error message:
"Note: GenericContainer.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details."
Could it be that the public T ReturnIt() { return thing; } is the cause of the error, and is this the wrong way to go about returning object that is contained in the Container-class?
I did not get any further information when I tried to compile it with -Xlint:unchecked.
What do I make of the error message?
Code that caused the error:
class GenericContainer {
public static void main(String[] args) {
Container BookStorage = new Container <Book>();
Book thejavabook = new Book("The Java book");
BookStorage.Store(thejavabook);
}
}
class Book {
private String title;
Book(String title) {
this.title = title;
}
}
class Container <T> {
private T thing;
public void Store(T obj) {
thing = obj;
}
public T ReturnIt() {
return thing;
}
}
Your BookStorage variable should be defined like this:
Container<Book> BookStorage = new Container <Book>();
I've rewritten your code to fix the problem and to use java naming standards:
package com.sandbox;
public class Sandbox {
public static void main(String[] args) {
Container<Book> bookStorage = new Container<Book>(); //fix for your warning!
Book theJavaBook = new Book("The Java book");
bookStorage.store(theJavaBook);
}
}
class Book {
private String title; //this is unused
Book(String title) {
this.title = title;
}
}
class Container<T> {
private T thing;
public void store(T obj) {
thing = obj;
}
public T returnIt() {
return thing;
}
}
Emphasis on this line:
Container<Book> bookStorage = new Container<Book>(); //fix for your warning!
You forgot to put the <Book> on the left hand side of your assignment.
Related
Here is some part of the practice.
I created an abstract parent class called Equipment, which has four child classes as shown as ConcreteMixer. Then the exercise asked me to create a class named Job, in which its constructor is as shown in the figure. I can’t understand the meaning of the list parameter, but I still created a class according to its requirements, and set it in It is instantiated in the main function.
This is the result of instantiation. I don’t know what the result of this parameter instantiation has to do with Equipment and its subclasses
public abstract class Equipment {
String requirement;
public Equipment(String requirements){
this.requirement=requirements;
}
public String getRequirement() {
return requirement;
}
}
public class ConcreteMixer extends Equipment{
public ConcreteMixer(String requirement){
super(requirement);
}
public String toString(){
return requirement;
}
#Override
public boolean equals(Object obj) {
if(obj instanceof ConcreteMixer) {
ConcreteMixer that = (ConcreteMixer) obj;
return this.requirement.equals(that.requirement);
} return false;
}
}
public Job(Address location, String description,List<Equipment> requiredEquipment, Date plannedDate) {
this.location = location;
this.description = description;
this.requiredEquipment = requiredEquipment;
this.plannedDate = plannedDate;
}
public static void main(String[] args) {
Job s= new Job(new Address("Star street",16, "da","London"),"mixer",new
ArrayList<Equipment>(),new Date(12,5,21));
System.out.println(s);
}
}
and this is the result for the main method
location:Address isLondonStar street16da
description:mixer
requiredEquipment:[]
plannedDate:day:12
month:5
year:21
As shown, your image shows nothing about using (or defining) your Equipment subclasses
But the point of the parameter is that the job can use multiple of any Equipment type
List<Equipment> e = new ArrayList<>();
e.add(new ConcreteMixer("concrete"));
Job j = new Job(..., e,...);
I have three classes: Labradors, Kennels and Show. The Kennel contains a private ArrayList of
Labradors. As shown:
Labradors.java:
public class Labradors {
private String name;
private String description;
public Labradors(String n, String d) {
name = n;
description = d;
}
public String getName() {
return name;
}
}
Kennel.java:
import java.util.ArrayList;
public class Kennel{
private ArrayList<Labradors> labs;
public Kennel() {
labs = new ArrayList<Labradors>();
}
public void addDog(Labradors l) {
labs.add(l);
}
}
and
Show.java
class Show
{
public static void main(String args[])
{
Labradors Dave = new Labradors("Dave", "Good dog!");
Labradors Bob = new Labradors("Bob", "Likes tummy rubs!");
Kennel niceHome = new Kennel();
niceHome.addDog(Dave);
niceHome.addDog(Bob);
for (Labradors lab: niceHome.labs ) {
System.out.println(lab.getName());
}
}
}
My for-each loop in Show gives me the following error:
Show.java:12: error: labs has private access in Kennel
for (Labradors lab: niceHome.labs ) {
^
1 error
Clearly one solution would be to make the ArrayList public, but my understanding of encapsulation is that best practice means it should be private and a Getter written. But how do I do this?
I feel this should have a really easy answer, but I'm having difficulty tracking it down...
NB - I'm using openjdk version 11.0.6 on Ubuntu 19.10.
Inside Kennel Class make a getter function
import java.util.ArrayList;
public class Kennel{
private ArrayList<Labradors> labs;
public Kennel() {
labs = new ArrayList<Labradors>();
}
public void addDog(Labradors l) {
labs.add(l);
}
public ArrayList<Labradors> getLabs(){
return this.labs;
}
}
Then access from main function like this
class Show
{
public static void main(String args[])
{
Labradors Dave = new Labradors("Dave", "Good dog!");
Labradors Bob = new Labradors("Bob", "Likes tummy rubs!");
Kennel niceHome = new Kennel();
niceHome.addDog(Dave);
niceHome.addDog(Bob);
for (Labradors lab: niceHome.getLabs()) {
System.out.println(lab.getName());
}
}
}
Help please, I get the following message, in the following code that I have:
listaFinal = (ArrayList<PuntoNota>) getIntent().getSerializableExtra("miLista");
AdapterDatos adapter = new AdapterDatos(this, listaFinal);
PuntoNota.java
public class PuntoNota implements Serializable{
private String punto;
private String nota;
public PuntoNota (String punto, String nota){
this.punto = punto;
this.nota = nota;
}
public String getPunto(){
return punto;
}
public String getNota(){
return nota;
}
}
AdapterDatos:
public AdapterDatos(Context context, ArrayList<PuntoNota> puntoNotaList) {
this.context = context;
this.puntoNotaList = puntoNotaList;
}
The application is working well, but I get the following message:
Unchecked cast: 'java.io.Serializable' to 'java.util.ArrayList ' less ... (Ctrl + F1).
about this code: (ArrayList ) getIntent (). getSerializableExtra ("myList"); will it be advisable to delete or hide this message?
Root cause: This is a warning from IDE, getSerializableExtra return a Serializable, and you are trying to convert to ArrayList<PuntoNota>. It might throw ClassCastException at runtime if the programe cannot cast it to your expected type.
Solution: In android to pass a user-defined object around, your class should implements Parcelable instead of Serializable interface.
class PuntoNota implements Parcelable {
private String punto;
private String nota;
public PuntoNota(String punto, String nota) {
this.punto = punto;
this.nota = nota;
}
protected PuntoNota(Parcel in) {
punto = in.readString();
nota = in.readString();
}
public String getPunto() {
return punto;
}
public String getNota() {
return nota;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(punto);
dest.writeString(nota);
}
public static final Creator<PuntoNota> CREATOR = new Creator<PuntoNota>() {
#Override
public PuntoNota createFromParcel(Parcel in) {
return new PuntoNota(in);
}
#Override
public PuntoNota[] newArray(int size) {
return new PuntoNota[size];
}
};
}
At sender side
ArrayList<PuntoNota> myList = new ArrayList<>();
// Fill data to myList here
...
Intent intent = new Intent();
intent.putParcelableArrayListExtra("miLista", myList);
At receiver side
ArrayList<? extends PuntoNota> listaFinal = getIntent().getParcelableArrayListExtra("miLista");
You can set a warning Suppression #SuppressWarnings annotation.
Example:
#SuppressWarnings("unchecked")
listaFinal = (ArrayList<PuntoNota>) getIntent().getSerializableExtra("miLista");
It is an annotation to suppress compile warnings about unchecked generic operations (not exceptions), such as casts. It essentially implies that the programmer did not wish to be notified about these which he is already aware of when compiling a particular bit of code.
You can read more on this specific annotation here:
SuppressWarnings
Additionally, Oracle provides some tutorial documentation on the usage of annotations here:
Annotations
As they put it,
"The 'unchecked' warning can occur when interfacing with legacy code written before the advent of generics (discussed in the lesson titled Generics)."
I am currently working with XML files, and am searching to have a better way to avoid try/catch blocks in a nice way.
Here is the thing. Let's say I have an XML file.
<A>
<BB>37</BB>
<CC>
<DDD>1</DDD>
</CC>
</A>
In fact, I turn this into an object, which means that I can do
myXml.getA() and so on.
In my code, I search a lot for given elements in this object, which means that I have a lot of lines like
int ddd = myXml.getA().getCC().getDDD();
The thing is that some elements may not be there, and for example another XML element can be like that only :
<A'>
<BB'>37</BB'>
</A'>
So if I try to get ddd, getCC() raises a NullPointerException.
In the end, I end up coding it like that :
int ddd;
try{
ddd = myXml.getA().getCC().getDDD();
}
catch (NullPointerException e){
ddd = 0;
}
This works but the code becomes really ugly.
I am searching for a solution to have something like
int ddd = setInt(myXml.getA().getCC().getDDD(), 0);
0 being the default in case the method raises an exception.
Is there a nice way to do that ?
Up to now, I couldn't find a solution that do not raise errors.
Thx for your help !
EDIT: Just not to get XML related answers.
I showed the xml part for everybody to understand the problem.
In my code, I don't have access to the XML, but only the object that represents it.
To make it short, what I'd really love is some kind of isNull method to test my getters.
This is sort of an annoyance of working with jaxb. in my company, we do enough work with jaxb that it was worth writing an xjc plugin which generated "safe" versions of every getter that were guaranteed to return non-null values for any non-trivial value (immutable instances in the case that a sub-object did not really exist).
Here's an example of what our generated model entities look like:
public class ExampleUser implements Serializable {
private final static long serialVersionUID = 20090127L;
#XmlAttribute
protected String name;
#XmlAttribute
protected String email;
public final static ExampleUser EMPTY_INSTANCE = new ExampleUser() {
private static final long serialVersionUID = 0L;
#Override
public void setName(java.lang.String value) { throw new UnsupportedOperationException(); }
#Override
public void setEmail(java.lang.String value) { throw new UnsupportedOperationException(); }
};
public String getName() {
return name;
}
public void setName(String value) {
this.name = value;
}
public String getEmail() {
return email;
}
public void setEmail(String value) {
this.email = value;
}
}
public class ExampleAccount implements Serializable {
private final static long serialVersionUID = 20090127L;
protected ExampleUser user;
#XmlElement(name = "alias")
protected List<String> aliases;
#XmlAttribute
protected String id;
#XmlAttribute
protected String name;
public final static ExampleAccount EMPTY_INSTANCE = new ExampleAccount() {
private static final long serialVersionUID = 0L;
#Override
public void setUser(com.boomi.platform.api.ExampleUser value) { throw new UnsupportedOperationException(); }
#Override
public List<String> getAliases() { return java.util.Collections.emptyList(); }
#Override
public void setId(java.lang.String value) { throw new UnsupportedOperationException(); }
#Override
public void setName(java.lang.String value) { throw new UnsupportedOperationException(); }
};
public ExampleUser getUser() {
return user;
}
public void setUser(ExampleUser value) {
this.user = value;
}
public List<String> getAliases() {
if (aliases == null) {
aliases = new ArrayList<String>();
}
return this.aliases;
}
public String getId() {
return id;
}
public void setId(String value) {
this.id = value;
}
public String getName() {
return name;
}
public void setName(String value) {
this.name = value;
}
public ExampleUser safeGetUser() {
return (getUser() != null) ? getUser() : ExampleUser.EMPTY_INSTANCE;
}
}
So you could write this code without fear of NPE:
userEmail = account.safeGetUser().getEmail();
You can look at the Null objec pattern.
For example :
public class A {
private C c;
public C getC() {
if (c == null) {
c = new C(0); // the "null object"
}
return c;
}
}
public class C {
private int d;
public C(int d) {
this.d = d;
}
public int getD() {
return d;
}
}
But personnaly, i have a bad feeling with this code :
int ddd = myXml.getA().getCC().getDDD();
It is a strong violation of the law of Demeter. The class invoker have a too large knowledge of A, C and D. This code will be clearly difficult to adapt and maintain.
The two general approaches to this sort of problem are the null object pattern that other answers have already covered, and type safe nulls such as Scala's Option.
http://www.scala-lang.org/api/current/scala/Option.html
There are a few Java versions of Option knocking around.
http://functionaljava.googlecode.com/svn/artifacts/2.20/javadoc/fj/data/Option.html
http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/Optional.html
Type safe nulls can be particular useful when combined with the flatmap.
Use Apache common-beanutils to create your set method. It will use reflection and then you have only a single place to catch the errors.
It would look something like this (haven't coded it so excuse syntax errors).
int getInt(Object root, String beanPattern, int defaultValue)
{
try
{
return PropertyUtils.getNestedProperty(root, beanPattern);
}
catch (Exception e)
{
return 0;
}
}
This would be called like so.
int ddd = getInt(myXml, "A.CC.DDD", 0);
Can't you just write a function which is general enough to be called for each value, and is returning the value or 0.
Something like
myGetSomething(FOO){
try {getFOO} catch ...
}
Then your Code itself looks nice, but the function has basically a try-catch for each call.
Use Xpath query instead of get methods. It will give you an empty list if it cannot find the element path.
List ddds = myXml.query("/AA/BB/CC/DDD");
if (!ddds.empty()) {}
The correct syntax depends on the XML library you use.
Write part of the code in Groovy or Xtend; both support the ?. syntax which returns null of the left hand side of the expression evaluates to null. They also get rid of the useless get so you can write:
myXml.a?.cc?.ddd
The syntax of Xtend is worse when compared to Groovy but it compiles to plain Java, so you just need to add a single JAR with some helper classes to your code to use the result.
I have a program on my computer that simulates a server on the internet and the fake server needs to be able to send multiple data types to some classes. Like for instance at one point of the program the server needs to send an int to a class then convert that int to a string and send it to another.
Basically what I am asking is if a method can have multiple data types for an input(Does this make sense? if not ill try to explain better). Is there any way to do this without creating many different methods?
Edit: Also is there a way to tell the difference between the types passed in (to prevent errors)
You can have a method which takes Object which is any type. In Java 5.0 and later primitives will be auto-boxed and passed as an object as well.
void method(Object o);
can be called using
method(1);
method("hello world");
method(new MyClass());
method(null);
If I understand correctly, you're asking if a method foo() can have multiple different inputs for its parameters
That way foo(Integer i) and foo(String s) are encased in the same method.
The answer: yes, but it's not pretty
foo(Object o)
Is your method declaration
Now you need to sort out the different types of possibilities
if(o instanceof Integer){
stuff();
} else if (o instanceof String){
moreStuff();
}
Just chain those else/if statements for the desired result.
What you want are Generic methods or classes.
to check what type an object is you'll have to use the 'instanceof' method
you can either make an entire class generic or just a single method, an example of a generic class:
package javahowto;
public class Member<T> {
private T id;
public Member(T id) {
this.id = id;
}
public T getId() {
return id;
}
public void setId(T id) {
this.id = id;
}
public static void main(String[] args) {
Member<String> mString = new Member<String>("id1");
mString.setId("id2");
System.out.printf("id after setting id: %s%n", mString.getId());
//output: id after setting id: id2
Member<Integer> mInteger = new Member<Integer>(1);
mInteger.setId(2);
System.out.printf("id after setting id: %d%n", mInteger.getId());
//output: id after setting id: 2
}
Now you now what to look for I'm sure you'll find the best solution to your problem.
check out:
http://download.oracle.com/javase/tutorial/java/generics/index.html
http://en.wikipedia.org/wiki/Generics_in_Java
...
Well I have also wondered and wrote below block. I think instanceof better but I tried getclass.
public static void main(String[] args){
System.out.println(method("This is a test"));
}
private static String method(Object o){
System.out.println(o.toString());
String status = "";
String className;
String[] oList = {"Double","Integer","String","Double","Float","Byte","Short","Long","Character","Boolean" };
for(int i = 0;i<oList.length;i++){
className = "java.lang." + oList[i];
Class testClass;
try {
testClass = Class.forName(className);
if(o.getClass().equals(testClass)){
status = "Your object is " + oList[i];
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
return status;
}
You could use the "hashed adapter" pattern.
Public interface Adapter {
Public void handle(object o);
}
Public class StringAdapter implements Adapter {
Public void handle(String st) { // stuff ...
}
Public class IntegerAdapter implements Adapter {
Public void handle(Integer intgr) { // stuff ...
}
Private static final Map adapters = new HashMap();
Adapters.put(string.class, new stringAdapter());
Adapters.put(Integer.class, new IntegerAdapter());
Public void handleMe(Object o) {
Adapters.get(o.getClass()).handle(o);
}
Ive always liked this more than the ol' cascade of ifs and else's.
On my iPad so sorry about formatting and terseness and speellling.