If i put object of A class as argument of someMeth(Object o), how can i access to this object methods? I cant change or overrdie someMeth(Object o).
...
void someMeth(Object o) {
o.setS("example"); -- exception : setS() is undefined for type Object
}
...
class A {
private String s;
String getS () {
return s;
}
void setS(String value) {
s = value;
}
}
...
someMeth(new A());
Try casting the object o to they type A like so:
A newObj = (A) o;
Then you can do:
newObj.setS("example");
Or a shorter, one line version:
((A)o).setS("example");
Try to convert type of reference:
void someMeth(Object o) {
if (o instanceof A) {
((A) o).setS("example");
}
}
Related
I am trying to call the overloaded method using if-else statement to decide which type of argument to pass so that appropriate method can be invoked. I am getting compilation error.
any idea why I am getting compilation error ? If call method separately using if-else check outside , it works fine.
public class A {
}
public class B {
}
public class RuleCheck {
public void check(A a) {
}
public void check(B b) {
}
}
public class Test {
public static void main(String[] args) {
A a = new A();
B b = new B();
testRule(a);
testRule(b);
}
private static void testRule(Object o) {
RuleCheck ruleCheck = new RuleCheck();
ruleCheck.check(o instanceof A ? (A) o : (B) o);//Compilation problem here : Cannot resolve method 'check(java.lang.Object)'
//Following code works fine
if (o instanceof A)
ruleCheck.check((A) o);
else if (o instanceof B)
ruleCheck.check((B) o);
}
}
I'm working on a project where I use Foo which is class that's implemented with an interface, FooExpression, and a separate concrete class called Replacement.
Replacement class uses hashmap:
private Map<Foo, FooExpression> replacementMap;
Replacement class uses put method:
public Expression put(Foo foo, FooExpression exp) {
return replacementMap.put(foo, exp);
}
The Replacement class has a method called get:
public FooExpression get(Foo foo) {
return replacementMap.get(foo);
}
The Foo class has a method, applyReplacement:
#Override
public FooExpression applyReplacement(Replacement r) {
Foo foo = new Foo(name);
FooExpression e = r.get(foo);
return e;
}
The Foo class uses an instance variable:
private String name;
The Foo class uses an equal and hashCode():
#Override
public boolean equals(Object o) {
if (!(o instanceof Foo)) {
return false;
} else {
return name.equals(o);
}
}
#Override
public int hashCode() {
return name.hashCode() + 41;
}
The FooExpression interface uses the applyReplacement method:
FooExpression applyReplacement(Replacement r);
Everytime I used applyReplacement method it returns null, simply because of the "new" instantiation.
I'm just wondering if there's a way to implement the Foo without erasing the existing value from the Replacement class? And I can't use generics for this one.
Your equals() method is wrongly implemented, currently it checks:
if o instanceof Foo
and if name.equals(o)
But o is in this case an instance of Foo. Your name though is an instance of String. This will never return true as a String will never be equal to a Foo.
You have to change your equals method accordingly:
#Override
public boolean equals(Object o) {
if (!(o instanceof Foo)) {
return false;
}
Foo foo = (Foo) o;
return name.equals(foo.name);
}
Which can also be simplified to:
#Override
public boolean equals(Object o) {
return o instanceof Foo && name.equals(((Foo) o).name);
}
I have tried:
package ro.ex;
import java.io.IOException;
import java.lang.reflect.Type;
class Ex {
public boolean isIns(Object o, Class t) {
o instanceof t;
}
public static void main(String[] args) throws IOException {}
}
above code will raise unknown class "t"
My question is: How to pass above code.
update:
following code can't pass intellij idea syntax checker
public boolean isIns(Object o, Class<?> t) {
return o instanceof t;
}
so the right code in idea is:
public boolean isIns(Object o, Class<?> t) {
return t.isAssignableFrom(o.getClass());
}
the more simple way is:
package ro.ex;
import java.io.IOException;
import java.lang.reflect.Type;
class Ex {
public boolean isIns(Object o, Class t) {
return t.isInstance(o);
}
public static void main(String[] args) throws IOException {
Object r = new Ex().isIns("", String.class);
System.out.println(r + "\t\t" + new Exception().getStackTrace()[0].getFileName() + ":" + new Exception().getStackTrace()[0].getLineNumber());
}
}
If you write x instanceof t, then t must be a class. In your isIns method, t is not a class, it is a variable of type Class.
The class Class, however, does offer methods with which you can decide whether some other class is a subclass of it: Class.isAssignableFrom(Class). So you can change you method to:
public boolean isIns(Object o, Class t)
{
return t.isAssignableFrom(o.getClass());
}
(I also changed your code so that the result of is returned to the caller.)
I have no idea what you are trying to do with your method, but the instanceof syntax is wrong.
public boolean isIns(Object o, Class t) {
return o instanceof t;
}
instanceof keyword checks with a Valid class name not with variable name. That's the compiler error.
For ex : o instanceof String, if you write like below, it won't compile
public boolean isIns(Object o, String str) {
return o instanceof str; //err, o instance of String is correct way to check.
}
And I slightly changed your method signature to match the statement.
You should use the dinamic equivalent of instanceof from Class class.
http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#isInstance(java.lang.Object)
public void isIns(Object o, Class t) {
t.isInstance(o);
}
Check for nulls if needed.
In your code below, t should be the name of a Java class (e.g. String). In your code, you've passed a variable name which is not appropriate:
public void isIns(Object o, Class t) {
o instanceof t;
}
Since an instanceof check is a one-liner, I'm not sure why you are wrapping it in a method. But if you insist on doing so, perhaps this is what you want:
public static boolean isIns(Object o, Class<?> t) {
return c.isInstance(o);
}
But two notes:
Lots of instanceof checks generally indicate bad design.
A Java programmer will be much more comfortable seeing instanceof rather than isIns(...).
maybe you want something like this?
public class test2 {
class c {
}
public test2() {
c obj = new c();
System.out.println(isIns(obj));
}
public boolean isIns(Object o) {
return (o instanceof c);
}
public static void main(String argv[]) {
new test2();
}
}
EDIT: Removed senceless Class parameters.
The error:
CAP#1 is not a fresh type
The code:
public Boolean isAssigned(HttpServletRequest request, String name, Foo foo) {
Boolean isAssigned = false;
if ((foo.getClass()) request.getSession().getAttribute(name) != null) {
isAssigned = true;
}
return isAssigned;
}
What is the solution?
May not be what you are looking for but it answers the question in the title.
The Class<T> class has a cast method which can cast any object to its own type T. Obviously it will throw a ClassCastException if the object cannot be cast to that type.
public <T> T castTo(Class<T> t, Object o) {
return t.cast(o);
}
public <T> T castTo(T t, Object o) {
return (T) castTo(t.getClass(), o);
}
public void test() {
String s = "Hello";
Object b = s;
String c = castTo(String.class, b);
String d = castTo("Some String", b);
}
If you want to test whether
request.getSession().getAttribute(name)
is of type Foo and execute a method method on it afterwards you could simply try using instanceof and cast:
if (request.getSession().getAttribute(name) instanceof Foo) {
((Foo) request.getSession().getAttribute(name)).method();
}
I'd like to create a generic enum-based mapper for IBatis. I'm doing this with the below code. This does have compile time errors, which I don't know how to fix. Maybe my solution is just plain wrong (keep in mind the use of IBatis), in such case please suggest something better.
Any help appreciated.
What I want to achieve is to define subsequent mappers as:
public class XEnumTypeHandler extends CommonEnumTypeHandler<X> {
}
The current code:
public class CommonEnumTypeHandler<T extends Enum> implements TypeHandlerCallback {
public void setParameter(ParameterSetter ps, Object o) throws SQLException {
if (o.getClass().isAssignableFrom(**T**)) {
ps.setString(((**T**) o).value().toUpperCase());
} else
throw new SQLException("Excpected ParameterType object than: " + o);
}
public Object getResult(ResultGetter rs) throws SQLException {
Object o = valueOf(rs.getString());
if (o == null)
throw new SQLException("Unknown parameter type: " + rs.getString());
return o;
}
public Object valueOf(String s) {
for (T pt : T.**values()**) {
if (pt.**value()**.equalsIgnoreCase(s))
return pt;
}
return null;
}
}
I've added error markings to the above code, the error messages are in order:
T cannot be resolved
The method value() is undefined for
the type T
The method values() is undefined for
the type T
The method values() is undefined for
the type T
I've solved this issue with the following code:
public class CommonEnumTypeHandler<T extends Enum> implements TypeHandlerCallback {
Class<T> clazz;
public CommonEnumTypeHandler(Class<T> clazz) {
this.clazz = clazz;
}
public void setParameter(ParameterSetter ps, Object o) throws SQLException {
if (o.getClass().isAssignableFrom(clazz)) {
ps.setString(((T) o).name().toUpperCase());
} else
throw new SQLException("Excpected " + clazz + " object than: " + o);
}
public Object getResult(ResultGetter rs) throws SQLException {
Object o = valueOf(rs.getString());
if (o == null)
throw new SQLException("Unknown parameter type: " + rs.getString());
return o;
}
public Object valueOf(String s) {
return Enum.valueOf(clazz, s);
}
}
Inheriting from this class I do:
public class SalesChannelTypeHandler extends CommonEnumTypeHandler<SalesChannel> {
public SalesChannelTypeHandler() {
super(SalesChannel.class);
}
public SalesChannelTypeHandler(Class<SalesChannel> clazz) {
super(clazz);
}
}
I'm not sure what you're doing (a general overview in words would be nice), but:
You can't do isAssignableFrom(T) (you need a Class object), and you can't do instanceof T either (generics are non-reified). You may want to pass Class<T> type tokens instead.
Have you looked at EnumMap?
See also
Java Tutorials/Runtime Type Tokens
Neal Gafter's Blog - Super Type Tokens
Josh Bloch - Typesafe Heterogenous Container (THC) pattern (PDF)
It's still not clear what is desired, but perhaps it's something along the lines of this:
enum Color { BLACK, WHITE; }
public static void main(String[] args) {
Color c = Enum.valueOf(Color.class, "black".toUpperCase());
System.out.println(c); // prints "BLACK"
}
So we use Enum.valueOf that takes a type token Class<T extends Enum<T>>, and ask it for the enum constant with a given name. valueOf is NOT case-insensitive, but by conventions, all constants should be in uppercase, so we simply take the query string and turn it .toUpperCase().
As pointed by Polygenelubricants, you need to pass concrete runtime types around, e.g. Class<?> instead of syntactic compiletime types like generic parameters. Here's a rewrite how you could use it:
public abstract class CommonEnumTypeHandler<E extends Enum<E>> implements TypeHandlerCallback {
private Class<E> enumClass;
public CommonEnumTypeHandler(Class<E> enumClass) {
this.enumClass = enumClass;
}
public void setParameter(ParameterSetter ps, Object o) throws SQLException {
if (enumClass.isInstance(o)) {
ps.setString((enumClass.cast(o)).name().toUpperCase());
} else {
throw new SQLException("Excpected ParameterType object than: " + o);
}
}
public Object getResult(ResultGetter rs) throws SQLException {
try {
return Enum.valueOf(enumClass, rs.getString());
} catch (IllegalArgumentException e) {
throw new SQLException("Unknown parameter type: " + rs.getString(), e);
}
}
}
Which you can then use as follows:
public class XEnumTypeHandler extends CommonEnumTypeHandler<X> {
public XEnumTypeHandler() {
super(X.class);
}
}