code snippet:
for( String token : tokens )
{
try
{
Url url = as("mycompany", "someapikey").call(shorten(token));
}
}
what do the 'as' and the 'call' mean. Are they keywords in java?
i was browsing and i found this code and i would like to understand what it means.
thank you in advance.
Looks like it's using the bit.ly library to shorten URLs. the for loop is iterating through strings in a collection, tokens. it then creates a shortened URL via the bit.ly library. These aren't keywords in Java, they are just method names.
android bit.ly library: http://code.google.com/p/bitlyj/
No, they are regular methods. The as() method should be in the class this is from (or a superclass), while the call() method is defined for the type returned by as().
It would be helpful to have a link back to the original source where you found this, as more context is often useful.
as and call are not keywords in Java.
It seems that as(String s1, String s2) is a method that returns an object that has a method call(..).
That method call(..) is invoked on the return value of as(..).
Maybe a static import?
For example, if class Foo has a static method as(), you can use
import static Foo.as;
{
//now can do this:
as(); //equal to Foo.as();
}
Related
I am developing a Java applet where I call a javascript function:
boolean isAllowed = (boolean) win.eval("isPointMarkCreationAllowed()");
and I would like to check if that function exists, like we do in javascript:
if (isPointMarkCreationAllowed == 'function')
is there anyway to do that in Java?
Without actually having tried it, wouldn't
win.eval("typeof isPointMarkCreationAllowed == 'function'");
do exactly what you want and return a Boolean (true or false)?
You can use reflection to test if a method exists.
For example if you have an object foo, you can get all the methods declared in the class of that object in the following:
Method[] methods = foo.getClass().getMethods();
This returns an array of the methods declared in the class.
Then just use a for loop to check if a specific method exists in the array returned
for (Method m : methods)
{
if (m.getName().equals(someString))
{
//do something
}
}
someString is the name of the method you're looking for, which is "isPointMarkCreationAllowed" in your case.
Use the following site to learn about reflections in Java
http://docs.oracle.com/javase/tutorial/reflect/member/methodType.html
I have a class that must have some static methods. Inside these static methods I need to call the method getClass() to make the following call:
public static void startMusic() {
URL songPath = getClass().getClassLoader().getResource("background.midi");
}
However Eclipse tells me:
Cannot make a static reference to the non-static method getClass()
from the type Object
What is the appropriate way to fix this compile time error?
The Answer
Just use TheClassName.class instead of getClass().
Declaring Loggers
Since this gets so much attention for a specific usecase--to provide an easy way to insert log declarations--I thought I'd add my thoughts on that. Log frameworks often expect the log to be constrained to a certain context, say a fully-qualified class name. So they are not copy-pastable without modification. Suggestions for paste-safe log declarations are provided in other answers, but they have downsides such as inflating bytecode or adding runtime introspection. I don't recommend these. Copy-paste is an editor concern, so an editor solution is most appropriate.
In IntelliJ, I recommend adding a Live Template:
Use "log" as the abbreviation
Use private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger($CLASS$.class); as the template text.
Click Edit Variables and add CLASS using the expression className()
Check the boxes to reformat and shorten FQ names.
Change the context to Java: declaration.
Now if you type log<tab> it'll automatically expand to
private static final Logger logger = LoggerFactory.getLogger(ClassName.class);
And automatically reformat and optimize the imports for you.
As for the code example in the question, the standard solution is to reference the class explicitly by its name, and it is even possible to do without getClassLoader() call:
class MyClass {
public static void startMusic() {
URL songPath = MyClass.class.getResource("background.midi");
}
}
This approach still has a back side that it is not very safe against copy/paste errors in case you need to replicate this code to a number of similar classes.
And as for the exact question in the headline, there is a trick posted in the adjacent thread:
Class currentClass = new Object() { }.getClass().getEnclosingClass();
It uses a nested anonymous Object subclass to get hold of the execution context. This trick has a benefit of being copy/paste safe...
Caution when using this in a Base Class that other classes inherit from:
It is also worth noting that if this snippet is shaped as a static method of some base class then currentClass value will always be a reference to that base class rather than to any subclass that may be using that method.
In Java7+ you can do this in static methods/fields:
MethodHandles.lookup().lookupClass()
I wrestled with this myself. A nice trick is to use use the current thread to get a ClassLoader when in a static context. This will work in a Hadoop MapReduce as well. Other methods work when running locally, but return a null InputStream when used in a MapReduce.
public static InputStream getResource(String resource) throws Exception {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
InputStream is = cl.getResourceAsStream(resource);
return is;
}
Simply use a class literal, i.e. NameOfClass.class
Try it
Thread.currentThread().getStackTrace()[1].getClassName()
Or
Thread.currentThread().getStackTrace()[2].getClassName()
getClass() method is defined in Object class with the following signature:
public final Class getClass()
Since it is not defined as static, you can not call it within a static code block. See these answers for more information: Q1, Q2, Q3.
If you're in a static context, then you have to use the class literal expression to get the Class, so you basically have to do like:
Foo.class
This type of expression is called Class Literals and they are explained in Java Language Specification Book as follows:
A class literal is an expression consisting of the name of a class, interface, array, or primitive type followed by a `.' and the token class. The type of a class literal is Class. It evaluates to the Class object for the named type (or for void) as defined by the defining class loader of the class of the current instance.
You can also find information about this subject on API documentation for Class.
I had the same problem !
but to solve it just modify your code as following.
public static void startMusic() {
URL songPath = YouClassName.class.getClassLoader().getResource("background.midi");
}
this worked fine with me hope it will also work fine with you.
Suppose there is a Utility class, then sample code would be -
URL url = Utility.class.getClassLoader().getResource("customLocation/".concat("abc.txt"));
CustomLocation - if any folder structure within resources otherwise remove this string literal.
Try something like this. It works for me. Logg (Class name)
String level= "";
Properties prop = new Properties();
InputStream in =
Logg.class.getResourceAsStream("resources\\config");
if (in != null) {
prop.load(in);
} else {
throw new FileNotFoundException("property file '" + in + "' not found in the classpath");
}
level = prop.getProperty("Level");
I have an XML defined which provides a payload path to a serialized XML. I would like to take these parameters and create an object and call a method in a class. What is the best approach to do this in Java?
XML
<RequestObjectType>com.test.model.QueryType</RequestObjectType>
<Class>com.test.api.Query</Class>
<Method>generalQuery</Method>
public void callRequestViaObj(String payloadXML, String payloadType, String api_className, String method){
Class c_payloadType = Class.forName(payloadType);
Class c_apiClass = Class.forName(api_className);
JAXBElement<c_payloadType> elemreq = (JAXBElement<c_payloadType>) JaxbUtils.XMLtoObj( payloadXML, JAXBContext.newInstance(c_payloadType) );
c_payloadType qreq = (c_payloadType) (elemreq.getValue());
//Would like to do something like this...
c_payloadType.newInstance().callMethod(method).with(qreq);
}
have a look at the reflection-api:
http://java.sun.com/developer/technicalArticles/ALT/Reflection/
section "Invoking Methods by Name"
There are many tools that will do this for you. One of them is Castor.
It looks like you just need to tweak the calls that use the reflection API. Try
c_payloadType.newInstance().getMethod(method, qreq.getClass()).invoke(qreq);
This assumes that c_payloadType is an instance of Class<?> and qreq is the argument you want to pass to the method call. I'm not sure if the JAXB code you've written correctly constructs those two objects.
Okay, so, here's what I have in code:
public void makeObject(int i){
String s = getString(i); //This returns the name of a class
new s(); //This is what I want to do
}
Can I do this?
No you can't do this, but what you're probably looking for is called 'reflection'.
Look at these series of (free) slides: http://www.slideshare.net/CiaranMcHale/java-reflection-explained-simply especially slide 11, but read the ones before that as well. It will give you an idea of what reflection is and a way to make a class by knowing the name (as a string) and how to instantiate a new instance of that class.
You can also find methods and fields by name, you can even modify existing classes in code.
Edit: for example the following code will return a class by string name
Class cls = Class.ForName("MyPackage.MyClassName");
return cls.NewInstance();
is it possible to configure GET method to read variable number of URI parameters and interpret them either as variable argument (array) or collection? I know query parameters can be read as list/set but I can't go for them in my case.
E.g.:
#GET
#Produces("text/xml")
#Path("list/{taskId}")
public String getTaskCheckLists(#PathParam("taskId") int... taskId) {
return Arrays.toString(taskId);
}
Thanks in advance
If I understand your question correctly, the #Path annotation can take a regular expression to specify a list of path components. For example, something like:
#GET
#Path("/list/{taskid:.+}")
public String getTaskCheckLists(#PathParam("taskid") List<PathSegment> taskIdList) {
......
}
There's a more extensive example here.
I am not submitting this as an answer as it is merely an edge case on the currently accepted answer which is what I've also used.
In my case (Jersey 1.19) /list/{taskid:.+} would not work for the edge case of zero variable parameters. Changing the RegEx to /list/{taskid:.*} took care of that. See also this article (which seems to be applicable).
Moreover, upon changing the regexp to cardinality indicator to * (instead of +) I also had to deal programmatically with the case of empty strings as I would translate the List<PathSegment> into a List<String> (to pass it into my DB-access code).
The reason I am translating from PathSegment to String is that I didn't want a class from the javax.ws.rs.core package to pollute my Data Access Layer code.
Here's a complete example:
#Path("/listDirs/{dirs:.*}")
#GET
#Produces(MediaType.APPLICATION_JSON)
public Response listDirs(#PathParam("dirs") List<PathSegment> pathSegments) {
List<String> dirs = new ArrayList<>();
for (PathSegment pathSegment: pathSegments) {
String path = pathSegment.getPath();
if ((path!=null) && (!path.trim().equals("")))
dirs.add(pathSegment.getPath());
}
List<String> valueFromDB = db.doSomeQuery(dirs);
// construct JSON response object ...
}