I have below interface and its implementation class.
Demo.java
public interface Demo{
void showDemo();
}
DemoImpl.java
#Service
public class DemoImpl implements Demo{
public void showDemo(){
//To Do
}
}
Now i have one class with static method which will internally call showDemo() as below.
DemoStatic.java
#Component
public class DemoStatic{
#Autowired
private Demo demo;
public static void callShowDemo(){
demo.showDemo(); //calling non static method from static method
}
}
Here i am calling non static method from static method. Is my design correct? Or do i need to change my design? Please suggest me.
Thanks!
You can do it this way
#Component
public class DemoStatic {
private static Demo demo;
#Autowired
public void setDemo(Demo d) {
demo = d;
}
public static void callShowDemo(){
demo.showDemo(); //calling static method from static method
}
}
No your design is not correct.
private Demo demo;
has to be
private static Demo demo;
You just cant use NON static members in a static method
The above code will not compile at all. You are trying to refer non-static reference from static method, which is not allowed in Java.
Refer this stackoverflow link for better understanding.
Make the following change:
public static Demo demo;
when you call DemoStatic.callShowDemo(),the demo may not been instand
Related
I was trying to access the non static method from class A to a static method in class B
#Component
public class B{
private static A aA1;
#Autowired
private A tA;
#PostConstruct
public void init(){
//<<<Make the enclosed method Static or remove this set>>>
B.aA1=tA;
}
public static void random method(){
aA1.doStuff();
}
}
Is it okay to make the init method static, as the sonar suggest
Or is there another way i could solve this?
I'm trying to understand how the static method calls from a Java enum works.
To see the full code of this "Working example"
I have the following scenario working, I don't know why
public enum Condition {
GREATER_THAN(PredicateBuilder::generateGreaterThan, ">"),
more values...
private Condition(BiFunction<PredicateBuilder, PredicateContent<?>, Predicate> predicate, String operator) {
this.operator = operator;
this.predicate = predicate;
}
This is the predicate builder, it's an interface implemented by a #Component from Spring:
#Component
public class PredicateLogicalBuilder<V extends Comparable> implements PredicateBuilder<V> {
#Override
public Predicate generateGreaterThan(PredicateContent<V> predicateContent) {
return predicateConversion(predicateContent,Condition.GREATER_THAN);
}
}
The static reference in above Condition enum doesn't complain about:
Non-static method cannot be referenced from a static context
and I don't why because now I'm trying to do something similar and it fails because the static reference of a method isn't static. In the code above is not static either.
Code I'm trying:
public interface MethodCalls<T> {
void randomMethod(T content);
}
#Component
public class TestEnumMethoCalls implements MethodCalls<SomeBean> {
#Override
public void randomMethod(SomeBean content){
System.out.println("Works!!!!");
}
}
public enum NotificationType {
ENUM_TEST_1(MethodCalls::randomMethod);
public final Function<SomeBean,Void> method;
private NotificationType(Function<SomeBean,Void> method){
this.method=method;
}
}
public class TestClass{
public void testMethtod(){
NotificationType.ENUM_TEST_1.method.apply(new SomeBean())
}
}
This piece of code fails saying the Non-static method cannot be referenced from a static context:
ENUM_TEST_1(MethodCalls::randomMethod);
I would like to have 2 answers:
Why the code of the "Working example" works.
If it's mandatory for my current test to use the instance of the MethodCalls how can be injected with DI to the enum (is a static context so I understand it might be tricky if not impossible).
Thanks for the help, now I understood why my "working example" works and how to "Fix" my current issue:
To fix it I have to pass an instance of the implementation of the interface as it's pointed out that enums can only access static methods or an instance of the object to access the method that way.
Final Code
public enum NotificationType {
ENUM_TEST_1(MethodCalls::randomMethod);
public final BiFunction<MethodCalls,SomeBean,Void> method;
private NotificationType(BiFunction<MethodCalls,SomeBean,Void> method){
this.method=method;
}
}
So when I call the apply it looks like this:
public class TestClass{
#Autowired MethodCalls methodCalls;
public void testMethtod(){
NotificationType.ENUM_TEST_1.method.apply(methodCalls,new SomeBean())
}
}
I someone finds out a cleaner way to do this, I would apreciate it.
I'm having the following flow:
manager.getObject.doSomthing();
Where doSomething() calls a static function from a Utils class, that in turn, calls a private static function e.g:
public class obj {
public void doSomething(){
Utils.do();
}
}
public class Utils {
public static void do(){
int test = doPrivate();
...
~do unrelated computation~
...
}
private static int doPrivate(){
return someComplexMethod();
}
}
And I would like to mock the doPrivate, so I would still be able to test the do() method
Any way to achieve it with powermockito?
Using powermock-api-mockito you can achieve this.
You can mock specific static method of a class. Below is the syntax:
import static org.powermock.api.support.membermodification.MemberMatcher.method;
import static org.powermock.api.support.membermodification.MemberModifier.stub;
stub(method(Utils.class, "doPrivate")).toReturn(response);
class Basics415 {
public static void main_hooo(){
out.println("1234");
}
void main_ho(){
}
}
In another file called Basics5.java:
public class Basics5 extends Basics415{
public static void main(){
main_hooo(); // We are accessing a public method of Class Basics415
main_ho(); // BUT WE CANNOT ACCESS A NON PUBLIC METHOD FROM SAME CLASS
}
}
Why can't we access main_ho() while we can access main_hooo() ?
Why basic415.main_ho or Basic415.main_hooo doesn't work inside the main method of Basics5?
Because the methods are static and therefore the classes need are needed to access them.
Basics4.method_Inside_Basics4()
So, after you edited a bunch of code ...
public class Basics5 extends Basics415{
public static void main(){
// accessing a static method in a static context.
Basics415.main_hooo();
// accessing an instance method in a static context.
final Basics415 b = new Basics415();
b.main_ho();
}
}
Your trouble is that the main metod of class Basics5 is a static method, static methods are defined at class level and not at instance level, then you can't use method not static in a static method.
You should access method_Inside_Basics4 method as Basics4.method_Inside_Basics4(). As Basics5 class extends Basics415 class, it inherits main_hooo method, which can be assessed from Basics5.
I have a class with no modifier(default), which has a public method called mymeth. I know I could access the method when I am within the package. However I would like to access the method when I am outside the package. does anyone has an Idea on how it could be done. theoretically I think it should be possible since public method means access by the world. here is the example of my class and method:
class myclass{
public void mymeth(int i,int b){
.....
}
}
set myclass class to be public.
**FYI, Classes in Java start from upper Case letter
Directly you cannot. 'public' makes everything visible. But if you can't see the class, it's difficult to call anything. However,
You can extend the default class with a public class, eventually myMeth is exposed.
PubClass.java
package p1;
class DefClass{
public void myMeth(){
System.out.println("from myMeth!");
}
}
public class PubClass extends DefClass{
public PubClass(){
super();
}
}
MainClass.java
package p2;
class MainClass {
public static void main(String[] args) {
p1.PubClass pub = new p1.PubClass();
pub.myMeth();
}
}
output:
from myMeth!
A real practical use for this would be, overriding a public known method in that hidden class. You can implement a public method in a hidden class, so the world can call your public method (public implementation rather) without the class being exposed. For example the public method of the Object class is overridden here by DefClass:
PubClass.java
package p1;
class DefClass{
public String toString(){
return "DefClass here. Trying to explain a concept.";
}
}
public class PubClass extends DefClass{
public PubClass(){
super();
}
}
MainClass.java
package p2;
class MainClass {
public static void main(String[] args) {
p1.PubClass pub = new p1.PubClass();
System.out.println(pub.toString());
}
}
output:
DefClass here. Trying to explain a concept.
public interface SomeInterface{
public void mymeth();
}
class MyClass implements SomeInterface{
public void mymeth(){
}
}
//is in the same package as MyClass
public MyClassFactory{
public SomeInterface create(/*parameters*/){
//create instance from parameters
//For your case
MyClass instanceOfAnyClassThatImplementsSomeInterface = new MyClass(/*pass the parameters*/);
return instanceOfAnyClassThatImplementsSomeInterface;
}
}
One of the ways is already defined in answers but If you want to restrict the public access of the class then you can create an interface and access the method through it.
Set myclass as public then put it in the build path of the class you need to use myclass.
In your code, myclass has the default (package-level) access modifier. It should be declared using the public access modifier so that it is accessible outside its package. For details, read more about Controlling Access in Java.
As a side note, the Java standards require you to capitalize each word in the class name, so you should use MyClass. I recommend you the Java Conventions document.
Consider making another public class MyChild with the same package name as MyClass and expose the method from MyChild class
public class MyChild extends MyClass {
public void myTestMethod(){
super.myTestMethod
}
}
Now in your class where you want to use the method, simply use the instance of MyChild class
MyChild m = new MyChild();
m.myTestMethod();
Cheers :)