I'm running SonarLint 3.4 and Oracle JDK 8. SonarLint is giving me this error:
Anonymous inner classes containing only one method should become lambdas (squid:S1604)
The interface, which I don't have control over, is setup like this:
public interface Interface {
static String staticMethodOne() {
return "abc";
}
default String methodOne(String input) {
return "one: " + input;
}
default String methodTwo(String input) {
return "two: " + input;
}
}
This is the code that generates the error:
public class Main {
public static void main(String[] args) {
callMethodOne(
new Interface() {
#Override
public String methodOne(String input) {
return ("override: " + input);
}
}
);
}
private static void callMethodOne(Interface instance) {
System.out.println(instance.methodOne("test"));
}
}
Since "Interface" is not a functional interface I don't see a way to replace it with a lambda. Is this a bug in SonarLint or am I missing something?
Confirmed as a bug in SonarJava; time to wait for the next SonarLint update.
https://jira.sonarsource.com/browse/SONARJAVA-2654
Related
I'm trying to create a javac plugin which will do some simple source validation for test classes. Essentially I want to ensure that this piece of code is invalid:
#RunWith(Parameterized.class)
class Test {
}
i.e. The RunWith annotation must not contain a Parameterized value. I'm able to get to the point of detecting this but I'm unsure how to produce an error correctly; I want the compile to fail with an error. Of course I can throw an exception, but that doesn't seem right.
I'm following the excellent examples from http://www.baeldung.com/java-build-compiler-plugin. My code currently looks like this:
public class EnsureCorrectRunsWithPlugin implements Plugin {
public static final String NAME = "MyPlugin";
private Context context;
public String getName() {
return NAME;
}
public void init(JavacTask task, String... args) {
context = ((BasicJavacTask) task).getContext();
log("Hello from " + getName());
task.addTaskListener(new TaskListener() {
public void started(TaskEvent e) {
// no-op
}
public void finished(TaskEvent e) {
if (e.getKind() != TaskEvent.Kind.PARSE) {
return;
}
e.getCompilationUnit().accept(new TreeScanner<Void, Void>() {
#Override
public Void visitAnnotation(AnnotationTree annotation, Void aVoid) {
if (annotation.getAnnotationType().toString().equals(RunWith.class.getSimpleName())) {
log("visiting annotation: " + annotation.getAnnotationType());
List<? extends ExpressionTree> args = annotation.getArguments();
for (ExpressionTree arg : args) {
log(" value: " + arg.toString());
if (arg.toString().equals(Parameterized.class.getSimpleName())) {
// Produce an error here...
}
}
}
return super.visitAnnotation(annotation, aVoid);
}
#Override
public Void visitClass(ClassTree node, Void aVoid) {
log("visiting class: " + node);
return super.visitClass(node, aVoid);
}
}, null);
}
});
}
private void log(String message) {
Log.instance(context).printRawLines(Log.WriterKind.NOTICE, message);
}
}
Thanks for any guidance.
You can use Trees.printMessage to output an error message. The first argument controls whether its a warning or an error, and Kind.Error will generate an error.
So assuming you stashed Trees into a variable trees, you can do something like:
this.trees.printMessage(Kind.Error, "Error from JavaC plugin", tree, compilationUnitTree)
The third variable, tree, indicates the error span.
While reading online, I came across the following:
public interface UnaryFunction<T>
{
T apply(T arg);
}
.......
private static UnaryFuntion<Object> ID_FUNC = new UnaryFunction<Object>
{
Object apply(Object arg)
{
return arg;
}
};
public static <T> UnaryFunction<T> idFunction()
{
return (UnaryFunction<T>) ID_FUNC;
}
In main:
public static void main(String[] args)
{
String[] strings = {"Peter", "Paul", "Mary"};
UnaryFunction<String> names = idFunction();
for(String s : strings)
{
System.out.println(names.apply(s));
}
Number[] numbers = {1, 2.0, 3L};
UnaryFunction<Number> nums = idFunction();
for(Number n : numbers)
{
System.out.println(nums.apply(n));
}
}
My question is, why do we need a generic interface here?
Would simply the following suffice:
public interface UnaryFunction
{
Object apply(Object arg); //Object as return type and argument type, instead.
}
? What is the need here to use generics?
And, what is actually a generic singleton factory? What is it good for?
Thanks.
The generic singleton factory is the idFunction in your example. Without it you would have a choice between two ugly alternatives, either require a cast wherever you use it, like this:
public class ExampleWithoutGenericSingletonFactory {
static UnaryFunction<Object> ID_FUNC = new UnaryFunction<Object>() {
public Object apply(Object arg) {
return arg;
}
};
public static void main(String[] args) {
BigDecimal b = new BigDecimal("1234.1241234");
BigDecimal b1 = (BigDecimal)(ID_FUNC.apply(b)); // have to cast here >_<
System.out.println("engineeringstring val of b1 = "
+ b1.toEngineeringString());
}
}
or make separate implementations for every type you want to support:
public static UnaryFunction<String> ID_FUNC_STRING = new UnaryFunction<String>() {
public String apply(String arg) {
return arg;
}
};
public static UnaryFunction<Number> ID_FUNC_NUM = new UnaryFunction<Number>() {
public Number apply(Number arg) {
return arg;
}
};
public static UnaryFunction<BigDecimal> ID_FUNC_DECIMAL = new UnaryFunction<BigDecimal>() {
public Number apply(BigDecimal arg) {
return arg;
}
};
giving you some ugly verbose cut-n-pasted code with a different name for every type that you have to keep straight. But since you know it's a pure function and the types get erased, you can have only one implementation (ID_FUNC) and have the singleton factory idFunction return it.
You would use this for cases where you have one function implementation that you want to be able to specify different types on, where the implementation is stateless.
The example could be better, since it only calls toString on the objects returned from the function call there's no demonstrated benefit from the factory. If the example showed using type-specific methods on the objects returned then the benefit might be more apparent.
An unchecked cast warning comes up when you do this, but it's safe to suppress it (which is what Joshua Bloch advises).
Still working on the same project (Java-based shell) and tried to run it - and got a strange error. I was working with a single class that represents one of the commands, and, because of the fact that school computers have no compilers, I use ideone. Anyway, I am getting an error and, while I have seen it before, the placement is really weird. The error:
Main.java:56: error: no enclosing instance of type LIST_Command is in scope
public FAKE_CMD(int i) {this.msg = i;System.out.println(i);}
^
Shouldn't this be in a place that is CALLING the constructor, or a static method of the class?
And here is the code (in its entirety, let me know what I should trim or edit it out yourself) Yes, this makes it an SSCCE.
package javashell.ver2.command;
import java.io.*;
import java.util.*;
class LIST_Command { /*extends Command*/
public static Map<String, Command> commands = new HashMap<>();
public String description() {
return "List all commands, their descriptions, or usages.";
}
public String usage() {
return "list <cmds | desc | usage>";
}
public boolean runCmd(String[] cmdArgs, PrintStream output) {
try {
if (cmdArgs.length == 0) {
return false;
}
else if (cmdArgs.length > 0) {
if (cmdArgs[0].equals("cmds")) {
for (Map.Entry<String, Command> cmd : /*main.Main.*/commands.entrySet()) {
output.println(cmd.getKey());
}
}
else if (cmdArgs[0].equals("desc")) {
for (Map.Entry<String, Command> cmd : /*main.Main.*/commands.entrySet()) {
output.println(cmd.getValue().description());
}
}
}
return true;
}
catch (Exception e) {
return false;
}
}
public static void main(String[] args) {
commands.put("test1", new FAKE_CMD(1));
commands.put("test2", new FAKE_CMD(2));
new LIST_Command().runCmd(new String[] {"cmds"}, System.out);
}
abstract class Command {
public abstract String usage();
public abstract String description();
public abstract boolean runCmd(String[] cmdArgs, PrintStream output);
}
static class FAKE_CMD extends Command {
int msg;
public FAKE_CMD(int i) {
this.msg = i;
System.out.println(i);
}
public String usage() {
return "usagetest" + msg;
}
public String description() {
return "descriptiontest" + msg;
}
public boolean runCmd(String[] cmdArgs, PrintStream output) {
return true;
}
}
}
Command is an inner class, which doesn't seem to make sense since it is contained in a class that should be its subclass. Anyway, that is the cause of your error: regardless of whether FAKE_CMD is itself static or not, it needs an enclosing instance of LIST_Command since it extends Command.
Note a possible subtlety in Java's terminology: inner class means a non-static nested class, therefore it implies the need for an enclosing instance.
The constructor of FAKE_CMD need to call its superclass' (Command's) constructor. However, since the superclass is not static, Java has no way of instantiate a superclass instance before constructing a FAKE_CMD.
I see about decorator example in Python:
def makebold(fn):
def wrapped():
return "<b>" + fn() + "</b>"
return wrapped
def makeitalic(fn):
def wrapped():
return "<i>" + fn() + "</i>"
return wrapped
#makebold
#makeitalic
def hello():
return "hello world"
print hello() ## returns <b><i>hello world</i></b>
And got some curious how it can be implement in Java, so I search and got some example using Decorator Design Pattern.
public class Main {
public static void main(String[] args) {
Wrapper word = new BoldWrapper(new ItalicWrapper());
// display <b><i>hello world</i></b>
System.out.println(word.make("Hello World"));
}
}
public interface Wrapper {
public String make(String str);
}
public class BoldWrapper implements Wrapper {
private Wrapper wrapper;
public BoldWrapper() {
}
public BoldWrapper(Wrapper wrapper) {
this.wrapper = wrapper;
}
#Override
public String make(String str) {
if(wrapper != null) {
str = wrapper.make(str);
}
return "<b>" + str + "</b>";
}
}
public class ItalicWrapper implements Wrapper {
private Wrapper wrapper;
public ItalicWrapper() {
}
public ItalicWrapper(Wrapper wrapper) {
this.wrapper = wrapper;
}
#Override
public String make(String str) {
if(wrapper != null) {
str = wrapper.make(str);
}
return "<i>" + str + "</i>";
}
}
How do I make this like the Python example above using a Java Annotation like this one:
public class Main {
public static void main(String[] args) {
#BoldWrapper
#ItalicWrapper
String str = "Hello World";
// Display <b><i>Hello World</i></b>
}
}
public #interface BoldWrapper {
public void wrap() default "<b>" + str + "</b>";
}
public #interface ItalicWrapper {
public void wrap() default "<i>" + str + "</i>";
}
I got some problem when I tried to make the sample, the problem is I don't know how I can pass the str value from the main method to the BoldWrapper and ItalicWrapper so it can concatenate and how to return it, so the main method can display the result that has been concatenate.
Please advise if there is something wrong with my understanding of annotation.
If you are particularly interested in doing this kind of stuff with annotations (you don't have to really):
This example should get you started:
public class AnnotationTest
{
#Target( ElementType.METHOD )
#Retention( RetentionPolicy.RUNTIME )
public static #interface TagWrapper
{
public String[] value() default {};
}
public static interface TextFragment
{
public String getText();
}
public static class TagWrapperProcessor
{
public static String getWrapperTextFragment( TextFragment fragment )
{
try
{
Method getText = fragment.getClass().getMethod( "getText" );
TagWrapper tagWrapper = getText.getAnnotation( TagWrapper.class );
String formatString = "<%s>%s</%s>";
String result = ( String ) getText.invoke( fragment );
for ( String tag : tagWrapper.value() )
{
result = String.format( formatString, tag, result, tag );
}
return result;
}
catch ( Exception e )
{
throw new RuntimeException( e );
}
}
}
public static class BoldItalicFragment implements TextFragment
{
private String _text;
public BoldItalicFragment( String text )
{
_text = text;
}
#Override
#TagWrapper(
{
"b", "i"
} )
public String getText()
{
return _text;
}
}
#Test
public void testStuff()
{
System.out.println( TagWrapperProcessor.getWrapperTextFragment( new BoldItalicFragment( "Hello, World!" ) ) ); // prints: <i><b>Hello, World!</b></i>
}
}
This is late but I think it may help the other people. From Java 8 with Function interface, we can write something close to python decorator like this:
Function<Function<String, String>, Function<String, String>> makebold = func -> input -> "<b>" + func.apply(input) + "</b>";
Function<Function<String, String>, Function<String, String>> makeitalic = func -> input -> "<i>" + func.apply(input) + "</i>";
Function<String, String> helloWorld = input -> "hello world";
System.out.println(makebold.apply(makeitalic.apply(helloWorld)).apply("")); // <b><i>hello world</i></b>
1) The link you cited is a good one - it does justice to the "Decorator Pattern" with respect to Java. "Design Patterns" themselves, of course, are independent of any particular OO language:
http://en.wikipedia.org/wiki/Design_Patterns
2) Here is another good link:
When to use the decorator pattern
In Java, a classical example of the decorator pattern is the Java I/O Streams implementation.
FileReader frdr = new FileReader(filename);
LineNumberReader lrdr = new LineNumberReader(frdr);
4) So yes, the "decorator pattern" is a good candidate for this problem.
Personally, I would prefer this kind of solution:
String myHtml =
new BoldText (
new ItalicText (
new HtmlText ("See spot run")));
5) However annotations are also an option. For example:
http://docs.oracle.com/javase/1.5.0/docs/guide/language/annotations.html
Python decorators very like java annotation, but that are very different principle.
Annotations, a form of metadata, provide data about a program that is not part of the program itself. Annotations have no direct effect on the operation of the code they annotate.
But you can prosessing class file with bytecode enhancement. I make a simple project for implementing that approach. It using javassist processing class file after building. It searching methods with specified annotation in classes. And add bridge methods for calling between wrapped method and original method. It look like, calling bridgeMethod() -> wrapperMethod() -> originalMethod(). Your can reference from https://github.com/eshizhan/funcwraps.
Although this doesn't resolve how to use annotations as you wanted, rather than using the "decorator design", I could propose you use the "builder design" if it suits better to your needs (it seems like so).
Quick usage example:
public class BuilderPatternExample {
public static void main(String args[]) {
//Creating object using Builder pattern in java
Cake whiteCake = new Cake.Builder()
.sugar(1)
.butter(0.5)
.eggs(2)
.vanilla(2)
.flour(1.5)
.bakingPowder(0.75)
.milk(0.5)
.build();
//Cake is ready to eat :)
System.out.println(whiteCake);
}
}
Output:
Cake{sugar=0.75, butter=0.5, eggs=2, vanila=2, flour=1.5, bakingpowder=0.0, milk=0.5, cherry=0}
For full implementation and a very good explanation, please check
http://javarevisited.blogspot.mx/2012/06/builder-design-pattern-in-java-example.html
In C# you can define delegates anonymously (even though they are nothing more than syntactic sugar). For example, I can do this:
public string DoSomething(Func<string, string> someDelegate)
{
// Do something involving someDelegate(string s)
}
DoSomething(delegate(string s){ return s += "asd"; });
DoSomething(delegate(string s){ return s.Reverse(); });
Is it possible to pass code like this in Java? I'm using the processing framework, which has a quite old version of Java (it doesn't have generics).
Pre Java 8:
The closest Java has to delegates are single method interfaces. You could use an anonymous inner class.
interface StringFunc {
String func(String s);
}
void doSomething(StringFunc funk) {
System.out.println(funk.func("whatever"));
}
doSomething(new StringFunc() {
public String func(String s) {
return s + "asd";
}
});
doSomething(new StringFunc() {
public String func(String s) {
return new StringBuffer(s).reverse().toString();
}
});
Java 8 and above:
Java 8 adds lambda expressions to the language.
doSomething((t) -> t + "asd");
doSomething((t) -> new StringBuilder(t).reverse().toString());
Not exactly like this but Java has something similar.
It's called anonymous inner classes.
Let me give you an example:
DoSomething(new Runnable() {
public void run() {
// "delegate" body
}
});
It's a little more verbose and requires an interface to implement,
but other than that it's pretty much the same thing
Your example would look like this in Java, using anomymous inner classes:
interface Func {
String execute(String s);
}
public String doSomething(Func someDelegate) {
// Do something involving someDelegate.execute(String s)
}
doSomething(new Func() { public String execute(String s) { return s + "asd"; } });
doSomething(new Func() { public String execute(String s) { return new StringBuilder(s).reverse().toString(); } } });
Is it possible to pass code like this
in Java? I'm using the processing
framework, which has a quite old
version of Java (it doesn't have
generics).
Since the question asked about the Processing-specific answer, there is no direct equivalent. But Processing uses the Java 1.4 language level, and Java 1.1 introduced anonymous inner classes, which are a rough approximation.
For example :
public class Delegate
{
interface Func
{
void execute(String s);
}
public static void doSomething(Func someDelegate) {
someDelegate.execute("123");
}
public static void main(String [] args)
{
Func someFuncImplementation = new Func()
{
#Override
public void execute(String s) {
System.out.println("Bla Bla :" + s);
}
};
Func someOtherFuncImplementation = new Func()
{
#Override
public void execute(String s) {
System.out.println("Foo Bar:" + s);
}
};
doSomething(someFuncImplementation);
doSomething(someOtherFuncImplementation);
}
}
Output :
Bla Bla :123
Foo Bar:123
You have all forgotten here that a C# delegate first of all - is thread safe.
These examples are just for a single thread App..
Most of the contemporary Apps are written on multithreaded concept..
So no one answer is the answer.
There is not an equivalent in Java