I know that there is a way to have a method to run automatically in java?. This is known as an IIFE in javascript, but is this possible in java?
Javascript IIFE:
(function() {
console.log('Hello!');
})();
Thank You! (I'm also just curious)
Here's an IIFE in Java:
((Function<String, String>) s -> {
String z = "'" + s + "'";
return z;
}).apply("aaa");
All of the following print "Hello world!"
JavaScript:
console.log((function() {
const x = "Hello world!";
return x;
})());
Java:
System.out.println(((Supplier<String>) () -> {
String x = "Hello world!";
return x;
}).get());
In Java it may feel more ergonomic to create a helper function to infer the type and execute the function for you:
public static <T> T iife(Supplier<? extends T> supplier) {
return supplier.get();
}
...
System.out.println(iife(() -> {
String x = "Hello world!";
return x;
}));
In general you might want to consider factoring out the function. But if the function is relatively small, and especially if it captures several variables, an IIFE may be more readable. I liken an IIFE to a block expression (which Java does not have).
Stumbled upon this question when looking for this idea myself. I think the closest thing Java has to JavaScript IIFEs would be an instance of an abstract class, whose only method, an execute method, is overriden during the instance creation and then executed immediately after the object's instantiation. You can even get the closure aspect of it too. However, you won't be able to change what the variable refers to inside the overriden method.
JavaScript:
let subject = 'World';
(() => {
console.log(`Hello, ${subject}!`);
})();
Java:
public abstract class Iife {
public abstract void execute();
}
public class Main {
public static void main(String[] args) {
String subject = "World";
new Iife() {
#Override
public void execute() {
System.out.println("Hello, " + subject + "!");
}
}.execute();
}
}
There is no direct way as mentioned by other people above.
Anonymous Inner Class with init() Initializer
I feel that this could be used like IIFEs but the problem is that it needs to be inside another class
Thread T = new Thread() {
private int num;
Thread init(int num){
this.num = num;
return this;
}
#Override
public void run() {
// computes and outputs the factorial of num
int res = 1;
for (int i = 1; i <= num; i++) {
res *= i;
}
System.out.println(res);
}
}.init(3);
The init() can be used to pass parameters to be used for working
In a static context, you can define code wrapped within brackets using the static modifier:
public class MyClass{
static{
System.out.println("Running static");
}
}
In the context of Objects, you can wrap the code in the same manner without the static modifier:
public class MyClass{
{
System.out.println("Initializing");
}
}
Java will automatically run the "public static void main(String[] args)" method in the class specified.
There is no IIFE in java.
Java is statically typed & compiled as opposed to javascript which is dynamically typed and interpreted.
In java there is only one entry point to a program which is the method main which is static and public.
In Groovy (JVM base language) you can use repl where defined method (functions are method in java terminology) can be invoked later which may be the nearest thing to IIFE.
Related
I wanted to use lambda function to return a value and I am not able to so the same. Why doesn't this work?
public class Main
{
public static void main(String[] args) {
System.out.println(() -> {
String s = "Akhilesh";
return s;
});
}
}
The other answer has given the explanation of why it would not work. Here is how you can make it work. In simpler terms, you must give Java some suggestion as to what the lambda should turn into, or else it wouldn't compile. (I suggest accepting their answer since it gives the actual reason for your problem. I am only posting this because I can empathize with wanting to print everything when learning anything Java and the frustration this must have come with.)
import java.util.function.Supplier;
public class Main
{
public static void main(String[] args) {
// prints "Main$$Lambda$1/0x0000000801185840#38af3868"
System.out.println((Supplier<String>) () -> {
String s = "Akhilesh";
return s;
});
Object obj = (Supplier<String>) () -> {
String s = "Akhilesh";
return s;
};
Supplier<String> supplier = () -> {
String s = "Akhilesh";
return s;
};
// prints "Main$$Lambda$2/0x0000000801186040#72ea2f77"
System.out.println(obj);
// prints "Main$$Lambda$3/0x0000000801186440#33c7353a"
System.out.println(supplier);
// prints "Akhilesh"
System.out.println(supplier.get());
}
}
See documentation for the java.util.function module.
Lambda expression is a short hand for an anonymous class implementation of a functional interface so you can only pass a lambda expression where the reference of a funtional interface.
There are overload of println() which take int, float, ArrayList, HashMap but there is no overload for println() which takes a functional interface as the input so you can't pass the lambda expression.
i have a question to Java Overload Methods.
Suppose i have an overload methods foo:
public static String foo(String x) {
return "foo-String: " + x;
}
public static String foo(Object x) {
return "foo-Object: " + x;
}
How can I implement to functions like
public static String useString() {
return(foo("useString"));
}
public static String useObject() {
return(foo("useObject"));
}
of which one uses the overloaded string method, and one the overloaded object method?
The call of the foo-Method should use an String input. (that means i do not want to work with a cast like
return(foo((Object)"useObject"));
Maybe you can help me with this problem
EDIT:
Above, just is an example for an exercise. I am trying to understand Overloads and Dispatch better and was looking for alternative solution for calling (and selecting) an overload method.
If we keep aside the motive behind this for a second and try to answer the direct question, you can create an object reference instead of using an explicit cast.
public static String useObject() {
Object obj = "useObject";
return foo(obj);
}
While the end result is the same, you avoid the need to have an explicit cast with this approach.
I guess this is a bit of cheating, but strictly speaking this doesn't use a cast on the syntax level:
public static String useObject() {
return(foo(Object.class.cast("useObject")));
}
If you want to use the method that receive an Object, you can upcast your string to object:
public class Main {
public static String foo(String x) {
return "foo-String: " + x;
}
public static String foo(Object x) {
return "foo-Object: " + x;
}
public static String useString() {
return(foo("useString"));
}
public static String useObject() {
Object x = "useObject";
return(foo(x));
}
public static void main(String[] args) {
System.out.println(Main.useObject());
}
}
The method public static String foo(Object x) will be called
When i use below code, the stackoverflow exception is seen. It looks like line 16 (i.e public my m1 = new my()) is repeatedly called. Can someone please explain on the reason for calling it continuously.
abstract class my {
static int i = 0;
my(){
System.out.println("my constructor " + i++);
}
public void mymethod() {
System.out.println("Abstract");
}
public my m1 = new my() {
public void mymethod() {
System.out.println("Inside Abstract");
}
};
You have an instance field, m1, which you initialize with a call to new my. Instance field initialization is done during construction.1 So you construct an instance, and constructing that instance requires constructing another instance to assign to m1; constructing that instance requires constructing an instance to assign to its m1; constructing it requires constructing another instance, which...
You get the idea.
As Peter said, by far the best way to understand how and why something is working the way it is is to use a debugger to step through the code. Using a debugger is not an advanced technique, it's a fundamental tool to learn early in the process of learning the language.
1 In fact, the compiler takes instance initializer code and inserts it at the beginning of every constructor in the class. So
class Foo {
private int bar = 42;
Foo() {
System.out.println("no args");
}
Foo(int arg) {
System.out.println("one arg: " + arg);
}
}
is actually compiled to
class Foo {
private int bar;
Foo() {
bar = 42
System.out.println("no args");
}
Foo(int arg) {
bar = 42
System.out.println("one arg: " + arg);
}
}
Is it possible through some method to assign a function to a variable in Java, like in PHP or JavaScript?
...Or does this area works on a different way when it comes to Java?
In Java you have Method and MethodHandles which can invoke a method via reflection but that is not supported in the language yet.
In Java 8, you will be able to use references to methods.
In today's java, no you can't.
The nearest you have is the interface : you don't store a function but the implementation of an interface defining the wanted function.
A typical example is the implementation of the Comparator interface :
Comparator<ProductSearchResult> c = new Comparator<ProductSearchResult>() {
public int compare(ProductSearchResult result1, ProductSearchResult result2) {
return result1.product.getRsId().compareTo(result2.product.getRsId());
}
};
Collections.sort(groupResults, c); // I pass a function, wrapped in my Comparator implementation
The nearest you have are inner classes combined with interfaces. These can carry not only one but many functions (methods) that can be delegated back to the master class methods if preferred. But this solution may easily be too heavyweight:
class Main {
interface X {
void doX();
}
class Ref1 implements X {
void doX() { doA(); };
}
class Ref2 implements X {
void doX() { doB(); };
}
void doA() { };
void doB() { };
void demo() {
X x = new Ref1();
x.doX();
}
}
This simulates something similar to Lambdas ... (you'll need a little more casting if you use anything other than Strings, but I'm keeping the example brief) ...
public class MyTest {
public static void main(String[] args) {
Lambda l = new Lambda() { public Object func(Object x)
{ return "Hello " + x; }
};
System.out.println(l.func("Bob"));
System.out.println(nowTryFromMethod(l));
System.out.println((new Lambda() { public Object func(Object x)
{ return "Goodbye " + x; }
}).func("Harry"));
}
private static Object nowTryFromMethod(Lambda l) {
return l.func("Jerry");
}
}
class Lambda {
public Object func(Object x) { return null; }
}
Output:
Hello Bob
Hello Jerry
Goodbye Harry
Update
Java supports reference to functions which is called Lambda from version 1.8
Java does NOT support that.
However, you can do that in JVM-Languages very comfortably, e.g. in Groovy.
Or you take a look at the command-pattern.
I am trying to do something I would not normally do, it is a bit odd, but I'd like to make it work. Essentially I have a factory that has to create objects by calling the constructor with different types of data (A and B take different types in the code below). I seem to have gotten my self stuck going down the generics route (I do need the code to be as compile time typesafe as possible). I am not opposed to writing the code differently (I'd like to keep the idea of the factory if possible, and I do not want to have to add in casts - so the "data" parameter cannot be an "Object").
Any thoughts on how to fix the code with generics or an alternative way of doing it that meets my requirements?
(Technically this is homework, but I am the instructor trying out something new... so it isn't really homework :-)
public class Main2
{
public static void main(String[] args)
{
X<?> x;
x = XFactory.makeX(0, "Hello");
x.foo();
x = XFactory.makeX(1, Integer.valueOf(42));
x.foo();
}
}
class XFactory
{
public static <T> X<T> makeX(final int i,
final T data)
{
final X<T> x;
if(i == 0)
{
// compiler error: cannot find symbol constructor A(T)
x = new A(data);
}
else
{
// compiler error: cannot find symbol constructor B(T)
x = new B(data);
}
return (x);
}
}
interface X<T>
{
void foo();
}
class A
implements X<String>
{
A(final String s)
{
}
public void foo()
{
System.out.println("A.foo");
}
}
class B
implements X<Integer>
{
B(final Integer i)
{
}
public void foo()
{
System.out.println("B.foo");
}
}
I don't see a way to make it work. I don't really think it should work either. When calling your makeX() function the calling code needs to know what integer parameter corresponds to what type of data to pass in. IOW, your abstraction is very leaky in the first place, and what you're really implementing is a rudimentary form of polymorphism, which you might as well use method overloading for, i.e.:
X makeX(String data) {
return new A(data);
}
X makeX(Integer data) {
return new B(data);
}
Of course it's a toy problem and all that. One way to make it work would be to make the client aware of implementation classes and add a Class<T> argument that you instantiate through reflection. But I suppose that would be kind of defeating the purpose.
I don't think what you're trying to do is possible without casting.
With casting, you have two options
if(i == 0)
{
x = new A((Integer)data);
}
else
{
x = new B((String)data);
}
}
or
class A
implements X<String>
{
A(final Object s)
{
}
}
...
class B
implements X<Integer>
{
B(final Object i)
{
}
}
Probably the closest thing you could get whilst retaining static type safety and having lazy construction is:
public static void main(String[] args) {
X<?> x;
x = aFactory("Hello").makeX();
x.foo();
x = bFactory(42).makeX();
x.foo();
}
private static XFactory aFactory(final String value) {
return new XFactory() { public X<?> makeX() {
return new A(value);
}};
}
public static XFactory bFactory(final Integer value) {
return new XFactory() { public X<?> makeX() {
return new B(value);
}};
}
interface XFactory() {
X<?> makeX();
}
So we create an instance of an abstract factory that creates the appropriate instance with the appropriate argument. As a factory, the product is only constructed on demand.
Clearly something had to give. What would you expect XFactory.makeX(1, "Hello") to do?
This is not possible without casting. As I have said elsewhere - generics don't remove the need for casting, but they mean that you can do all the casting in one place.
In the setup you describe, the factory method is exactly where all the under-the-hood work takes place. It's the spot where your code tells the compiler "I know you don't know what these types are, but I do, so relax.
It's entirely legit for your factory method to know that if i==1, then the data must be be of type Integer, and to check/enforce this with casting.