Just in case if you are trying to apply an instance method from the same object where your code runs
Arrays.asList("a", "b", "c").forEach(this::print);
Answer from Sergey Shcherbakov on Stack OverflowJust in case if you are trying to apply an instance method from the same object where your code runs
Arrays.asList("a", "b", "c").forEach(this::print);
Regardless of whether you use method references, lambda expressions or ordinary method calls, an instance method requires an appropriate instance for the invocation. The instance may be supplied by the function invocation, e.g. if forEach expected a BiConsumer<Chapter3,String> it worked. But since forEach expects a Consumer<String> in your case, there is no instance of Chapter3 in scope. You can fix this easily by either, changing Chapter3.print to a static method or by providing an instance as target for the method invocation:
public class Chapter3 {
public void print(String s) {
System.out.println(s);
}
public static void main(String[] args) {
Arrays.asList("a", "b", "c").forEach(new Chapter3()::print);
}
}
Here, the result of new Chapter3(), a new instance of Chapter3, will be captured for the method reference to its print method and a Consumer<String> invoking the method on that instance can be constructed.
Cannot make a static reference to a non-static method.
java - Method reference for static and instance methods - Stack Overflow
java - Cannot make a static reference to the non-static method fxn(int) from the type Two - Stack Overflow
Calling Non-Static Method In Static Method In Java - Stack Overflow
Videos
This error is the most damning of all that i have encountered so far. I am a first year at uni and doing a coursework assessment to create a small game. We must use polymorphism, ArrayLists, animations etc. It's in Processing, which is basically Java.I am trying to modify a boolean from a unrelated class, to a different one.
ver.1
public Class Objects {
public boolean isCollected = false;
}
Class Player {
void collision() {
if(x) {
Objects.isCollected = true;
}
}
} ERROR: Cannot make a static reference to a non-static method.....
ver2.
public Class Objects {
public boolean isCollected = false;
public void setIsCollected() {
isCollected = true;
}
}
Class Player {
void collision() {
if(x) {
Objects.setIsCollected();
}
}
}ERROR: Cannot make a static reference to a non-static method.....
Neither of the versions works, i tried adding an instance ofObjects object;
in the player class, but it only gives me a ERROR: NullPointerException - which i completely understand and knew it wouldn't work. Is it not possible to change the boolean isCollected without it being tied to a instance/object?
Why it is not allowing AppTest::makeUppercase?
The short answer is that AppTest::makeUppercase isn't valid "reference to an instance method of an arbitrary object of a particular type".
AppTest::makeUppercase must implement interface Function<AppTest, String> to be valid reference.
Details:
There are 4 kinds of method references in Java:
ContainingClass::staticMethodName- reference to a static methodcontainingObject::instanceMethodName- reference to an instance method of a particular objectContainingType::methodName- reference to an instance method of an arbitrary object of a particular typeClassName::new- reference to a constructor
Every single kind of method reference requires corresponding Function interface implementation.
You use as a parameter the reference to an instance method of an arbitrary object of a particular type.
This kind of method reference has no explicit parameter variable in a method reference and requires implementation of the interface Function<ContainingType, String>. In other words, the type of the left operand has to be AppTest to make AppTest::makeUppercase compilable. String::toUpperCase works properly because the type of parameter and type of the instance are the same - String.
import static java.lang.System.out;
import java.util.Arrays;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.function.UnaryOperator;
class ReferenceSource {
private String value;
public ReferenceSource() {
}
public ReferenceSource(String value) {
this.value = value;
}
public String doInstanceMethodOfParticularObject(final String value) {
return ReferenceSource.toUpperCase(value);
}
public static String doStaticMethod(final String value) {
return ReferenceSource.toUpperCase(value);
}
public String doInstanceMethodOfArbitraryObjectOfParticularType() {
return ReferenceSource.toUpperCase(this.value);
}
private static String toUpperCase(final String value) {
return Optional.ofNullable(value).map(String::toUpperCase).orElse("");
}
}
public class Main {
public static void main(String... args) {
// #1 Ref. to a constructor
final Supplier<ReferenceSource> refConstructor = ReferenceSource::new;
final Function<String, ReferenceSource> refParameterizedConstructor = value -> new ReferenceSource(value);
final ReferenceSource methodReferenceInstance = refConstructor.get();
// #2 Ref. to an instance method of a particular object
final UnaryOperator<String> refInstanceMethodOfParticularObject = methodReferenceInstance::doInstanceMethodOfParticularObject;
// #3 Ref. to a static method
final UnaryOperator<String> refStaticMethod = ReferenceSource::doStaticMethod;
// #4 Ref. to an instance method of an arbitrary object of a particular type
final Function<ReferenceSource, String> refInstanceMethodOfArbitraryObjectOfParticularType = ReferenceSource::doInstanceMethodOfArbitraryObjectOfParticularType;
Arrays.stream(new String[] { "a", "b", "c" }).map(refInstanceMethodOfParticularObject).forEach(out::print);
Arrays.stream(new String[] { "d", "e", "f" }).map(refStaticMethod).forEach(out::print);
Arrays.stream(new String[] { "g", "h", "i" }).map(refParameterizedConstructor).map(refInstanceMethodOfArbitraryObjectOfParticularType)
.forEach(out::print);
}
}
Additionally, you could take a look at this and that thread.
String::toUpperCase
is short version of
text -> {
return text.toUpperCase();
}
is again short version of
new Functon<String, String> (String text) {
Override
public String apply(String text) {
return text.toUpperCase();
}
}
so when you want AppTest::myMethod
you need
public class AppTest {
public String myMethod(){
return this.toString();
}
public void printFormattedString2(AppTest appTest, Function<AppTest, String> formatter){
System.out.println(formatter.apply(appTest));
}
public static void main(String[] args) {
AppTest appTest = new AppTest();
appTest.printFormattedString2(appTest, AppTest::myMethod);
}
}
because whole version looks so
appTest.printFormattedString2(appTest, new Function<AppTest, String>() {
@Override
public String apply(AppTest text) {
return text.makeUppercase2();
}
});
Since the main method is static and the fxn() method is not, you can't call the method without first creating a Two object. So either you change the method to:
public static int fxn(int y) {
y = 5;
return y;
}
or change the code in main to:
Two two = new Two();
x = two.fxn(x);
Read more on static here in the Java Tutorials.
You cannot refer non-static members from a static method.
Non-Static members (like your fxn(int y)) can be called only from an instance of your class.
Example:
You can do this:
public class A
{
public int fxn(int y) {
y = 5;
return y;
}
}
class Two {
public static void main(String[] args) {
int x = 0;
A a = new A();
System.out.println("x = " + x);
x = a.fxn(x);
System.out.println("x = " + x);
}
or you can declare you method as static.
The only way to call a non-static method from a static method is to have an instance of the class containing the non-static method. By definition, a non-static method is one that is called ON an instance of some class, whereas a static method belongs to the class itself.
You could create an instance of the class you want to call the method on, e.g.
new Foo().nonStaticMethod();