Why am I getting an empty array of annotations here - java

According to the doc and to this answer I should be having "Override" (or something similar) in the following code:
import java.lang.reflect.*;
import java.util.*;
import static java.lang.System.out;
class Test {
#Override
public String toString() {
return "";
}
public static void main( String ... args ) {
for( Method m : Test.class.getDeclaredMethods() ) {
out.println( m.getName() + " " + Arrays.toString( m.getDeclaredAnnotations()));
}
}
}
But, I'm getting an empty array.
$ java Test
main []
toString []
What am I missing?

Because the #Override annotation has Retention=SOURCE, i.e. it is not compiled into the class files, and is therefore not available at runtime via reflection. It's useful only during compilation.

I wrote this example to help me understand skaffman's answer.
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Method;
import java.util.Arrays;
class Test {
#Retention(RetentionPolicy.RUNTIME)
public #interface Foo {
}
#Foo
public static void main(String... args) throws SecurityException, NoSuchMethodException {
final Method mainMethod = Test.class.getDeclaredMethod("main", String[].class);
// Prints [#Test.Foo()]
System.out.println(Arrays.toString(mainMethod.getAnnotations()));
}
}

Related

Convert an int to Hex and check the assertion. Java AT

I have a task to write an #Test annotated method which uses Integer toHexString and asserts that 11 becomes b
This is how I tried this getting illegal start of expression:
import org.junit.Test;
import org.junit.Assert;
public class HexTest {
#Test
public static void main (String[] args){
static Integer.toHexString(11){
Assert.assertEquals("int to Hex", 'b', 11);
}
}
}
I would be so grateful if someone could tell me what is wrong and how to fix it.
Fixed:
import org.junit.Assert;
import org.junit.Test;
public class HexTest {
#Test
public void integerToHexStringTest() { // test method definition
// GIVEN
String expected = "b";
// WHEN
String actual = Integer.toHexString(11); // call method `toHexString(11)`
// THEN
Assert.assertEquals("int to Hex", expected, actual);
}
}
The problem is that you don't need the static keyword to call a static method. What you should be doing is calling the method, storing the result in a variable and checking if that variable holds the value you expect:
import org.junit.Test;
import org.junit.Assert;
public class HexTest {
#Test
public void testToHexString(){
String result = Integer.toHexString(11);
Assert.assertEquals("int to Hex", "b", result);
}
}

How to add annotation or any other marker to a field during runtime?

I am creating an object from another one using Java reflection API.
There is an annotation defined on the Class of the source object. However it is not defined on the Class of the target object.
I know it is not possible to dynamically add any annotation at runtime.
Also, there is no possibility of using Javassist because the classes are already by the time.
Is there any way to copy the value of the annotation to the target object during runtime ? It need not be by using annotation.
According to this post this you should try:
Java7:
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
public class Main {
public static void main(String[] args) throws Exception {
Greeter greetings = Greetings.class.getAnnotation(Greeter.class);
System.out.println("Hello there, " + greetings.greet() + " !!");
GreeterByHand greetingsByHand = Greetings.class.getAnnotation(GreeterByHand.class);
System.out.println("Hello there, " + greetingsByHand.greet() + " !!");
addAnnotationManually(GreeterByHand.class, instanceOfGreeterByHand("Yayy added by hand"), Greetings.class);
Greeter greetingsAgain = Greetings.class.getAnnotation(Greeter.class);
System.out.println("Hello there, " + greetingsAgain.greet() + " !!");
GreeterByHand greetingsByHandAgain = Greetings.class.getAnnotation(GreeterByHand.class);
System.out.println("Hello there, " + greetingsByHandAgain.greet() + " !!");
}
private static void addAnnotationManually(Class<? extends Annotation> targetAnnotation, Annotation annotationInstance, Class<Greetings> targetClass) throws Exception {
Field annotationsField = Class.class.getDeclaredField("annotations");
annotationsField.setAccessible(true);
#SuppressWarnings("unchecked")
Map<Class<? extends Annotation>, Annotation> originalAnnotations = (HashMap<Class<? extends Annotation>, Annotation>) annotationsField.get(targetClass);
originalAnnotations.put(targetAnnotation, annotationInstance);
}
public static GreeterByHand instanceOfGreeterByHand(final String greet) {
return new GreeterByHand() {
#Override
public String greet() {
return greet;
}
#Override
public Class<? extends Annotation> annotationType() {
return GreeterByHand.class;
}
};
}
}
(I don't know why you want to do that, i thinks there are some antipattern behind your code)
Greeter:
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
#Retention(RetentionPolicy.RUNTIME)
public #interface Greeter {
String greet() default "";
}
GreeterByHand:
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
#Retention(RetentionPolicy.RUNTIME)
public #interface GreeterByHand {
String greet() default "";
}
Greetings:
#Greeter(greet="Good morning")
#GreeterByHand
public class Greetings {}

java static import compilation error

Using java version 1.7.0_05
When i compile the below code it's give me testpackage could not be found error.
But if i remove the static keyword from "import static testpackage.TestStatic;" it's compiling successfully.
Test:
import java.io.*;
import java.util.*;
import static testpackage.TestStatic;
import static java.lang.Integer.MAX_VALUE;
public class Test {
public static void main(String args[]) {
System.out.println("hello world");
System.out.println("Maximum value of int variable using " +
"static import : "
+ MAX_VALUE);
}
}
TestStatic:
package testpackage;
import java.io.*;
import java.util.*;
public class TestStatic {
public static void testStatic() {
System.out.println("Inside Test Static");
}
public void testNormal(){
System.out.println("test normal");
}
public static void main(String args[]) {
System.out.println("hello world");
}
}
import static is for importing static members of classes, not whole classes. You could say "import static testpackage.TestStatic.testStatic;".
EDIT: fixed syntax
When you say import static testpackage.TestStatic; the compiler does not know what you want to import, you could mean import a static variable TestStatic in a class testpackage. In fact, I think you wanted to import testStatic() from the testpackage.TestStatic class,
For a method or field by name
import static testpackage.TestStatic.testStatic;
For all static methods and fields
import static testpackage.TestStatic.*;

Access annotation at runtime

How can I access in main whether check in the Sample class is true or false?
What should I write in Main class?
package annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
#Retention(RetentionPolicy.RUNTIME)
public #interface annotation {
public String name() default "Jimmy";
public boolean check() default false;
}
package annotation;
#annotation(name = "Jack", check = false)
public class Sample {
public String str = "Hi";
public void printHi(String str) {
System.out.println(str);
}
}
package annotation;
public class Main {
public static void main(String[] args) {
}
}
Use Sample.class.getAnnotation(annotation.class) to get your annotation instance, and call check() to get the check value:
System.out.println(Sample.class.getAnnotation(annotation.class).check());
Note that classes should start with an upper-case letter, and that naming an annotation "annotation" is quite confusing.

Java import class System

I have a question on class imports, It seems you can call a method with a reduced line if you have imported the class. I don't understand what is the name of this operation, and how is it possible...
For instance :
Why this code
public class test
{
public static void main (String args[])
{
System.out.print("Test");
}
}
Can be replaced by
import static java.lang.System.out;
public class test
{
public static void main (String args[])
{
out.print("Test");
}
}
What happens if you have also an object named "out" ?
Thanks in advance
What happens is that out from external class must be referenced by full name:
String out = "Hello World";
java.lang.System.out.println(out);
The variable out will shadow the static import and you will have to use the full name in order to use the function print.
import static java.lang.System.out;
public class Tester5 {
public static void main (String args[]) {
int out=0;
out.print("Test");
}
}
yields "cannot invoked print(String) on primitive type int. The same error is shown if out is an object.

Categories