For two utility classes with the same names, which contain only static methods, I proceeded as follows:
Simply imported the first
Created an instance of the second class.
Example:
package util1;
public class Utility {
public static void method() {
System.out.println("First Utility. static method");
}
}
package util2;
public class Utility {
public static void method() {
System.out.println("Second Utility. static method");
}
}
import util1.Utility;
public class Component {
private static final util2.Utility anotherUtility = new util2.Utility();
public static void usedByReflection() {
Utility.method();
anotherUtility.method();
}
}
Now I don't need to write a full second util-class name for invoke its methods, but maybe I did not foresee something...?
P.S:
The methods of the class Component are called through a reflection by a certain BlackBox. All the multithread-safe features are in BlackBox.
UPD: I have found better trick:
import util1.Utility;
public class Component {
private static final util2.Utility anotherUtility = null; // There are some changes
public static void usedByReflection() {
Utility.method();
anotherUtility.method();
}
}
Now I dont create new object, but is it possible to use it without any bugs?
IMO, this is confusing and could much more clearly be handled by something like:
public class CombinedUtilityComponent {
public static void usedByReflection() {
util1.Utility.method();
util2.Utility.method();
}
}
Or, better yet, in your code you can just fully qualify the class names and they become unique names without any confusing tricks.
Yes, this works. I wouldn't do it, though.
You're calling a static method as if it were an instance method. anotherUtility.method() has a useless reference to anotherUtility.
You also have an unnecessary instantiation of util2.Utility. This technique wouldn't work if the default constructor were disabled.
Related
I want to create a set of classes that allows me to write records
What I want to achieve is this
Record.write.field1();
Record.write.field2();
My understanding is that I can create multiple static nested objects but I'm struggling with it
I created the following
public abstract class Record{
public Write write;
}
public abstract class Write{
public static void field1();
}
The approach above hasn't helped me achieve that.
The questions I have is
Can I write a set of classes in a way so I can achieve the following pattern
Record.write.field1();
Record.write.field2();
This is so that I can scale it up when needing to add additional field
If I can, is this a good approach?
If I can't, what's the best approach?
Thank you
UPDATE: I can do Record.write but can't do Record.write.field15();
public class Record {
public static Write write;
}
public class Write {
public static void field15(){
System.out.println("Hello");
}
}
This allows you to write the code the way you want:
class Record {
public static Write write = new Write();
}
class Write {
public void field15(){
System.out.println("Hello");
}
}
public class Main {
public static void main(String[] args) {
Record.write.field15(); // prints "Hello"
}
}
Note that static methods are invoked on the class name, and instance methods are invoked on a specific instance value.
I couldn't think of a good way to name this. Basically I'm have a program where I want to have a default "pattern" almost I guess of how something should function. But I wanted to allow the use to create their own implementation (This is like an API) of the class and use that as a parameter instead, with the functionality inside. Is this the most efficient way to do it? If you don't understand that bad description here is an example.
public class SimpleStyle extends AbstractStyle {
public void personalizedImplementation() {
// manipulate the program this way
}
}
Then in the method
public static void do(Class<? extends AbstractSyle> style) {
// Use reflection in herre to get the implementation and do it
}
Is there a better and more efficient way to do something like this
You should not use reflection for this task if you can avoid it. It is less readable and more error-prone than well designed interfaces.
The basic solution (I’m not sure whether you already considered it) is to simply pass instances of AbstractStyle to your method:
public static void doSomething(AbstractStyle style) {
style.personalizedImplementation();
}
public static void main(String[] args) {
do(new SimpleStyle());
}
If you cannot use this approach – this depends on the specific use case – you could define an additional interface that handles the creation of the AbstractStyle instance:
public interface StyleFactory {
AbstractStyle createStyle();
}
public class SimpleStyleFactory implements StyleFactory {
#Override
public SimpleStyle createStyle() {
return new SimpleStyle(/* ... */);
}
}
public static void doSomething(StyleFactory styleFactory) {
AbstractStyle style = styleFactory.createStyle();
style.personalizedImplementation();
}
public static void main(String[] args) {
do(new SimpleStyleFactory());
}
Note: do is a Java keyword, so it can’t be used as an identifier. I used doSomething instead.
I am working on a project, and I have come across something i do not fully understand yet.
Every time I like to call a method from another class, or use a variable from a jform my netbeans says that I need to make it "static". Now I understand what static means, and I have created objects from the class that I use methods from, but even then netbeans says that I need to make the object static before i can use it in the MAIN() method. Even the jform variables like comboboxes.
can somebody please explain this?
thanks in advance!
EDIT:
this is some code from my project. It's very small but it should clarify the problem:
the Mainclass:
public class SpeeloTheek {
/**
* #param args the command line arguments
*/
public static Controller MainController = new Controller();
public static SummaryScreen MainSummaryScreen = new SummaryScreen();
public static void main(String[] args) {
// TODO code application logic here
MainSummaryScreen.setVisible(true);
MainController.SetFullScreen(MainSummaryScreen);
MainController.ComboBoxItemSelected(SummaryScreen.choiceBox);
}
the controller class:
package speelotheek;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.JComboBox;
import javax.swing.JFrame;
public class Controller {
//Method to make JFrame fullscreen//
public void SetFullScreen(JFrame frameToUse) {
frameToUse.setExtendedState(JFrame.MAXIMIZED_BOTH);
}
public void ComboBoxItemSelected(final JComboBox comboBoxToUse) {
comboBoxToUse.addItemListener(new ItemListener() {
#Override
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
WhichSummary(comboBoxToUse);
}
}
});
}
public void WhichSummary(JComboBox comboBoxToUse) {
System.out.println(comboBoxToUse.getSelectedItem());
}
}
EDIT2:
Thanks all :) I found the problem. I instantiated the class in the main method instead above the main method and it worked :)
In order to call non-static members of a class you need to instantiate an object.
Example:
Foo myObject = new Foo(); // myObject is an object of class Foo
Foo.callToStaticMember(); // static members can be called using the class name
myObject.callToNonStaticMember(); // non-static members require an object of the class
This is because your main method is a static method.
From a static method you can't call the non static method's or variablen.
You need to change your main method to a constructor.
Then this code will be executed when you make an new instance of this class.
If you're using Netbeans GUI Builder, what you want to do is work from the constructor, instead of the main method
public NewJFrame() {
initComponent();
jComboBox1.addItem("Hello");
// do everything with your components here
}
All the objects declared by the GUI Builder are non-static. They're not meant to be accessed from the main.
if you are trying to access non-static methods from the main method. It would not work. The reason being, that static methods/variables do not belong to the instance of the class.
If you do need to access a non static method in your main method of another class. the only way to do it is through the instance of the class.
So, you would need to say
MyClass object = new MyClass();
object.aMethod();
EDIT
Do you want your application to be all static? Basically, static would mean that it will have only one memory location. So, for eg: if a user selects a radio button on one screen. it modifies the value in your code, and another user selects another radio button, it will overwrite the previous user's value.
What you do need to do is something like this.
public static void main(String[] args) {
// TODO code application logic here
Application appObject = new Application();
appObject.setController(new Controller());
appObject.setSummaryScreen(new SummaryScreen()); // Or pass these values through a constructor. Setters are just one way to do it. Or better yet, use Spring DI.
appObject.performAction();
}
public Class Application {
public Controller MainController ;
public SummaryScreen MainSummaryScreen ;
.... getters and setters of these instance variables.
public performAction(){
MainSummaryScreen.setVisible(true);
MainController.SetFullScreen(MainSummaryScreen);
MainController.ComboBoxItemSelected(SummaryScreen.choiceBox);
}
}
While you are working within the main method, which is static
public static void main(String[] args){
}
you can only call static elements, such classes, enum or static methods.
If you want to call a method member of a class from your main method, you have two options
Make the method static
class ClassA{
public static void methodOne(){
}
}
public static void main(String[] args){
ClassA.methodOne();
}
Instantiate the class in your main and call the non-static method.
class ClassA{
public void methodOne(){
}
}
public static void main(String[] args){
ClassA classA = new ClassA();
classA.methodOne();
}
Advice
You have to take care while using static methods, because they share its memory.
when you create a new class ClassA classA = new ClassA();, for each new class you create, it stores its own non-shared memory variables, but when you use static methods, they share the memory which could be dangerous.
I have following code.
1st Class
package com.test;
public class CustomizeHere
{
private CustomizeMe customizeMe = new CustomizeMe();
public void setDescription()
{
customizeMe.setText("How about calling some method before me?");
}
}
2nd Class
package com.test;
public final class CustomizeMe
{
private String text = null;
public String getText()
{
return text;
}
public void setText(String text)
{
this.text = text;
}
}
3rd class
package com.test;
public class ReflectCustomizer
{
/**
* #param args
*/
public static void main(String[] args)
{
CustomizeHere customizeHere = new CustomizeHere();
// Requirement here is when customizeMe.setText() before method invocation we want to add some additional behaviour at run time like we should come to
// know setText() is invoked.
customizeHere.setDescription();
}
}
I wanted to know in above scenario can I anyway come to know that setText() method on CustomizeMe is being invoked? And I can't change code from customizeMe, but I have Instance of customizeMe at the runtime using reflection.
I can not change code in CustomizeMe and CustomizeHere classes. Also as java.lang.Reflect.Method class does not allow to attach any listner so that I would come to know that it is being invoked so Is there another way?
If your requirement is to set some parameters on the object before invoking some other methods, you can either have constructors that take these parameters, or to follow the Builder pattern if you have interdependencies between the various configuration options you want to create.
An advanced way is by defining an Aspect targeting the setText method which contains the additional logic you want to write. This would run for all invocations of that method on any instance of that the class this aspect targets.
Aspects are meant to address cross-cutting concerns, though.
I was wondering if anyone had a pattern that would help me achieve the following:
We have a JPA entity called Employee and on it there is a setLineManager method. We also have a separate updateLineStructureService, which is a Spring-managed service bean. We want to try and ensure that this setLineManager method can only be called from updateLineStructureService and not directly from any other class.
Is there a way to allow the service access to this method without exposing it to any other classes? I am aware that I could give the method package level access and put the service in the same package as Employee, but that will not fit our package structure so I would prefer not to do that. I am also aware that I could make the method private and just access it through reflection in this one place, but I do not like that solution at all.
Any ideas?
You can inspect the stacktrace (using Throwable#getStackTrace()) and see if it contains the allowed method on specified position.
In the following code snippet, System.PrivateEmployee is not visible outside the System class. Thus effectively privateMethod is private and can only be called from within the System class. Since System.PrivateEmployee extends System.PublicEmployee it can be used outside the System class as System.PublicEmployee
public class System
{
public static interface PublicEmployee { void publicMethod ( ) ; }
private static interface PrivateEmployee extends PublicEmployee { void privateMethod ( ) ; }
}
Use an inner class only available to the other service class:
public class Employee
{
static {
LineStructureService.registerEmployeeHelper(new EmployeeHelper() {
#Override
public void setLineManager(Employee emp, Object foo) {
emp.setLineManager(foo);
}
});
}
public static void init() {}
private void setLineManager(Object foo) { }
}
public class LineStructureService
{
private static volatile EmployeeHelper _helper;
static {
// ensure that Employee class is loaded and helper registered
Employee.init();
}
public static synchronized void registerEmployeeHelper(EmployeeHelper helper) {
_helper = helper;
}
public void doSomething(Employee emp)
{
// now this class can call setLineManager on Employee
_helper.setLineManager(emp, blah);
}
public interface EmployeeHelper {
public void setLineManager(Employee emp, Object foo);
}
}
The only way that a class can access private methods of other classes is with inner classes. If that is not an option, this can't be done.
One approach is to make two forms of Employee.
"BasicEmployee" has all the methods except setLineManager(). "ExtendedEmployee" extends BasicEmployee and adds a public void setLineManager(). (I'm assuming these are classes, but they could also be interfaces instead) Underneath the hood, everything is really a FullEmployee (for clarity, you could make BasicEmployee abstract). But, in the code, in all the classes except UpdateLineStructureService, you declare it as a BasicEmployee. Only in UpdateLineStructureService is it declared as a FullEmployee. So, only UpdateLineStructureService has easy access to setLineManager()
Now, a rogue coder could always cast their BasicEmployee to an ExtendedEmployee to access setLineManager(), so this isn't totally secure. But it's a reasonable pattern to limit access.
You could use AOP (e.g. AspectJ or CDI) to intercept the call to setLineManager(); if the caller is updateLineStructureService() call the method; if not do nothing, or raise an exception or whatever.