So, this is going to sound like an odd question, but I need to know how to get the Class object of a child Object in an inheritance situation for Java reflection.
The situation is this: I'm writing CraftBukkit plugins, Java plugins that work with CraftBukkit, a server-side-only plugin A.P.I. for Minecraft. At the moment, I'm making a plugin that is supposed to be like a "parent" to all of the other plugins I'm writing. It contains large amounts of extra useful Objects and utilities.
One class in the plugin is an Object class called myPlugin that I want all the main classes of all the other plugins to extend. (I know Object names shouldn't start with a lowercase letter, but the lowercase "my" is a trademark with my CraftBukkit plugins.)
One of the things that I want this myPlugin class to do is be able to handle commands to load plugins' data. Therefore, when the command is called, I want the plugin to basically call all of the methods in the plugin's main class that start with "load".
I know how to search through all the Methods in the Class for ones starting with "load" if I can just retrieve the Class, but if I try to call getClass() in the myPlugin class, I believe it's just going to return the myPlugin Class instead of the Class that extends myPlugin.
So, how can I retrieve the Class that extends myPlugin instead of the myPlugin class itself?
EDIT:
I feel that I should mention that I've considered creating an abstract method called mainClass() that will return the Class and making each plugin add this method and return their main class, but this is an ugly fix that I would prefer to avoid.
No it's the subclass name that is returned, consider:
public class ClassOne {
}
public class ClassTwo extends ClassOne {
}
public class Test {
public void someMethod(ClassOne one) {
System.out.println(one.getClass().getName());
}
}
public class Main {
public static void main(String[] args) {
ClassTwo t = new ClassTwo();
Test tst = new Test();
tst.someMethod(t);
}
}
The output is: ClassTwo
Related
Nowadays we are on writing some core application that is all other application will be relying on. Without further due let me explain the logic with some codes,
We used to have a single java file that was 1000+ lines long and each application was having it as class inside, so when there was a change, each application had to edit the java file inside of it or simply fix one and copy to all. This is hard to implement as much as it is hard to maintain. Then we end-up with creating this as a separate application that is divided to smaller part, which is easy to maintain and also a core maybe a dependency to other application so we fix in one place and all other code applications are fixed too.
I've been thinking for a some great structure for this for a while want to use a builder patter for this as below
TheCore theCore = new TheCore().Builder()
.setSomething("params")
.setSomethingElse(true)
.build();
The problem arises now. Like so, I initialized the object but now I'm having access to that objects public class only. This application actually will have many small classes that has public functions that I don't want them to be static methods that can be called everytime. Instead I want those methods to be called only if TheCore class is initilized like;
// doSomething() will be from another class
theCore.doSomething()
There are some ideas I produced like
someOtherClass.doSomething(theCore)
which is injecting the main object as a parameter but still someOtherClass needs to be initialized or even a static method which doesn't make me feel comfortable and right way to that.
Actually I do not care if initializing TheCore would bring me a super object that includes all other classes inside initialized and ready to be accessed after I initialized TheCore. All I want in this structure to have a maintainable separate app and methods avaiable if only the main object which is TheCore is this circumstances is initialized.
What is to right way to achive it? I see that Java does not allow extending multiple classes even it if does, I'm not sure it that is right way...
Thanks.
After spending significant amount of time of thought I ended up that
// doSomething() will be from another class
theCore.doSomething()
is not suitable since many java classes could possibly have identical method names. So...
// doSomething() will be from another class
theCore.someOtherClass.doSomething()
would be a better approach.
To make it easier to understand I'll have to follow a complex path to explain it which is starting from the package classes first.
Think that I have a package named Tools and a class inside SomeFancyTool
main
└─java
└─com
└─<domainName>
├─Tools
| └─SomeFancyTool.java
└─TheCore.java
Now this SomeFancyTool.java must have a default access level which is actually package level access, because I don't want this classes to be accessed directly;
SomeFancyTool.java
package com.<domainName>.Tools
class SomeFancyTool{
public String someStringMethod(){
return "Some string!";
}
public int someIntMethod(){
return 123;
}
public boolean someBooleanMethod(){
return true;
}
}
So now we have the SomeFancyTool.java class but TheCore.java cannot access it since it is accesible through its Tools package only. At this point I think of an Initializer class that is gonna be in the same package, initialize these private classes and return them with a function when called. So initiliazer class would look like this;
ToolsInitializer.java
package com.<domainName>.Tools
public class ToolsInitializer{
private SomeFancyTool someFancyTool = new SomeFancyTool();
public SomeFancyTool getSomeFancyTool(){
return someFancyTool;
}
}
Since ToolsInitializer.java can initialize all functional private classes inside in Tools package and also can return them as objects to outside of the package scope, still we are not able to use these methods as we cannot import com.<domainName>.SomeFancyTool from TheCore.java because it is package wide accessible. I think here we can benefit from implementation of the java interface. A class that is not functional alone, so no problem even if it is accessed since it's methods will be nothing but declarations.
At this point I'll rename SomeFancyTool.java to SomeFancyToolImplementation.java which it will be implementing the interface and call SomeFancyTool.java to the interface itself.
SomeFancyTool.java (now as an interface)
package com.<domainName>.Tools
public interface SomeFancyTool{
public String someStringMethod();
public int someIntMethod();
public boolean someBooleanMethod();
}
and lets rename prior SomeFancyTool.java and implement the interface
SomeFancyToolImplementation.java (renamed)
package com.<domainName>.Tools
class SomeFancyToolImplementation implements SomeFancyTool{
#override
public String someStringMethod(){
return "Some string!";
}
#override
public int someIntMethod(){
return 123;
}
#override
public boolean someBooleanMethod(){
return true;
}
}
Now our structure has become like this with the final edits;
main
└─java
└─com
└─<domainName>
├─Tools
| ├─SomeFancyTool.java
| ├─SomeFancyToolImplementation.java
| └─ToolsInitializer.java
└─TheCore.java
Finally we can use our TheCore.java class to call all initializer classes with their methods to receive all these private classes inside as an object. This will allow external apps to call and initialize TheCore first to be able to access other methods.
TheCore.java
public class TheCore{
private SomeFancyToolImplementation someFancyTool;
public static class Builder{
private SomeFancyToolImplementation someFancyTool;
public Builder(){
ToolsInitializer toolsInitializer = new ToolsInitializer();
someFancyTool = toolsInitializer.getSomeFancyTool();
}
public Builder setSomeValues(){
//some values that is needed.
return this;
}
public Builder setSomeMoreValues(){
//some values that is needed.
return this;
}
public TheCore build(){
TheCore theCore = new TheCore();
theCore.someFancyTool = someFancyTool;
return theCore;
}
}
}
All Done and it is ready to use. Now the functional package classes and its methods that it relying on if TheCore is initialized or not, cannot be accessed with out TheCore. And simple usage of this Library from a 3rd Party app would simply be;
3rd Party App
TheCore theCore = new TheCore.Builder()
.setSomeValues("Some Values")
.setMoreSomeValues("Some More Values")
.build();
theCore.someFancyTool.someStringMethod();
Note: Note that a the ToolsInitializer.java is still accessible and could be used the get private method without first calling TheCore but we can always set a checker inside getSomeFancyTool() method to throw error if some prerequisites are not satisfied.
I do not still know if this is a functional structural pattern to use or its just some hard thoughts of mine. And don't know if some pattern is already exist that I just could not see yet but this is the solution I end up with.
I am developing a library which needs some configuration information from project which would include this library. What I was thinking is to having some abstract methods in my library and force application to implement these methods.
What I am looking for is:
Class A in library having some static abstract methods, say
having a method named getURL();
A class B implements these static
methods in actual application and implement method getURL() from
class A.
In my library, I called A.getURL(), it should call method
implementation from class B which extends class A and should return me the url.
But an abstract method can't be static in Java. Is there some workaround to achieve same like functionality.
public abstract class A {
protected static A INSTANCE;
public static String getURL() {
return INSTANCE.getURL();
}
protected abstract String getURL0();
}
class B extends A {
static {
INSTANCE = new B();
}
#Override
protected String getURL0() {
return "application-specific url";
}
}
A static abstract method makes no sense, since the notion that an abstract method should be implemented by an extending class (which is part of OO), and static denotes a non instance method (not OO).
But I had a similar problem in a J2EE project recently, in which the library needed some specific configuration depending on the project that used it.
What we decided to do is to have a configuration file with a specific name in the project, that the library should read as soon as loaded. If the file and/or the required configurations were not found, an exception is thrown (you can create your own).
I think this way you can decouple implementation of the library from the projects using it.
Based on your answers to questions I would recommend the following:
Define an interface for a class that retrieves the properties like so:
interface LibaryDetails {
URL getURL();
String getName();
}
Then create a Factory method of some kind which causes your Library to run and do it's thing. Refactor your code out of the main so it can be accessed from here. Have this method take the interface as a parameter:
public class LibraryFactory{
public static void startLibrary(LibaryDetails details){
URL url = details.getURL();
String name = details.getName();
// start Library things
}
}
Now your Library only needs to expose the interface and the static Factory. Your Applications just needs to pass it's implementation of the LibraryDetails interface to the factory method and your library can access the information.
I'm designing UI Tests for a web application with Selenium in JUnit. I have a base test class with something like this from which I inherit my tests:
public class BaseTest {
protected TestSteps test;
protected Assertions assertion;
// set everything up...
}
and the tests then only look like this:
public class TestX extends BaseTest {
#Test
public testFeature1() {
test.clickSomething().enterSomething(); // method chaining
assertion.assertSomething();
//...
}
}
The problem I'm having: There are different modules in the web app, and Assertions/TestSteps methods that only apply to one module clutter the interface of the Assertions/TestSteps class for the other modules.
Thus I tried to split the Assertions/TestSteps up.
The problem is, the method chaining returns instances of TestSteps. Of course, when I have Module1TestSteps with method doSomethingSpecific() then I would expect test.clickSomething().doSomethingSpecific() to work, but it does not, because clickSomething() would return a TestSteps instance, not a Module1TestSteps instance.
I "solved" this by making an AbstractTestSteps<T extends AbstractTestSteps<T> class (which contains all the base TestSteps methods) protected abstract T getThis();.
I then extend this class like this:
public class BaseTestSteps extends AbstractTestSteps<BaseTestSteps> {
// Constructors
protected BaseTestSteps getThis() {
return this;
}
// that's it, the "base methods" are all inherited from AbstractTestSteps...
}
for the base TestSteps and
public class Module1TestSteps extends AbstractTestSteps<Module1TestSteps> {
// same constructors...
protected Module1TestSteps getThis() {
return this;
}
public Module1TestSteps doSomeThingSpecific() {
// do something
return getThis();
}
}
for my specialized TestSteps. It works for now, but I don't like it because of the following reasons:
All the general methods are in the AbstractTestSteps class, but they are used through an instance of BaseTestSteps
What if I have a submodule of Module1? I can't inherit from Module1TestSteps, only from AbstractTestSteps.
I think it's not trivial to understand the relation of these classes when one of my colleagues tries to add a new TestSteps class.
How can this be made better?
Use the Page Object pattern. That is, create an API for each page so that your tests describe navigating and interacting with pages in a way that describes the user's experience.
It has a few benefits that address your concerns:
It uses composition, not inheritance
It is easy to understand and explain to people maintaining the tests because the tests read like a description of somebody using the application
I'm new to Java and i want a refinement:
First of all,i am not sure if i can have 2 classes in the same file.
My question is what is each class when you see this sequence of code:
class Something {
//code here
} //end of class Something
public class SomethingElse {
//NO code here!!!
public static void main(String[] args) {
//code of main here
}//end of main
}
What's the role of the class Something Else and why there is no code inside?I know that is a very stupid question but there are some details that i don't really get and i want some help...
You can have more than one class per file, but only one class can be public and its name must match the name of the file (e.g. public MyClass in MyClass.java).
The public class of a file will be visible to the outside world, and in particular if the class has a public static main(String[] args) method, it can be used to start an application.
In your case for example, once you have compiled your file using javac, you will get files Something.class and SomethingElse.class.
Using the command java SomethingElse will tell the Java Virtual Machine to do the following:
Find the SomethingElse class, which must be in the SomethingElse.class file
call the main method, matching the signature I pasted above on this class (and putting any given argument in the args array).
You cannot call java Something because the class isn't public and doesn't have a main method. But other classes in your program (and in particular, SomethingElse, can use your Something class).
You can have just one public class per file, and the file must have the same name of the class. But you can have other private classes that just the file class will see. For example:
File Something.java
public class Something {
//Something can access SomethingElse's doSomething method.
private class SomethingElse {
public void doSomething() {
}
}
}
class SomethingToo {
}
File OtherSomething.java
public class OtherSomething {
//OtherSomething cannot access SomethingElse's doSomething method.
//But can access SomethingToo, if they are in the same package
}
You can have multiple classes defined in a same file. However there should only one class defined as public and file name will be that public class name.
In the No code here!!! you can have class variables and methods defined. Your main() is one such example.
In the above file, there are two classes SomethingElse (public) and Something. Now, this is normally done when the non-public class is called internally by the public class. Also, in the above code fragment, SomethingElse seems to be a 'driver' class. In other words, it does not have any functionality/data of its own, but is used to execute (drive) other classes (probably Something in this case)
You can have nested classes, but two separate, public classes are not allowed. Each public class should be in it's own file named the same as the class.
While it's possible to have 2 classes in the same file, its considered bad practice. Besides the decreased readability, it will eventually become difficult to find out where that class declaration actually took place. Plus, if you declare a variable relating to the class, but not the class sharing the .java name, javac will most likely have issues compiling.
If you have to do it, make sure the only place you are using the second class is within the class sharing the .java name. (E.g. only use a Something object within the SomethingElse class). Otherwise, separate all your classes into separate .java files.
Yes, you can have 2 or more classes in single Java file.
The only condition is only one class will contain main method with signature(public static void main(String[] args)).
And only one public class will be there. And with that public class name you can save your file - the file name has to match the name of the public class.
I've got the following classes set up:
public abstract class Process<T,S> {
...
}
public abstract class Resource<T, S extends Process<T, S>> {
protected S processer;
...
}
public class ProcessImpl<EventType1, EventType2> {
...
}
public class ResourceImpl extends Resource<EventType1, ProcessImpl> {
processer = new ProcesserImpl();
...
}
Everything is fine until I get to the ResourceImpl. I'm told that ProcessImpl is not a valid substitute for the bounded parameter <S extends Process<T,S>> of the type Resource<T,S>.
I've tried various ways of getting around this and keep hitting a wall.
Does anyone have any ideas?
public class ProcessImpl<EventType1, EventType2> {
...
}
Because ProcessImpl doesn't extend Process. Your ProcessImpl is not derived from Process, which is what you're declaring that parameter should be.
You might want to do something like this:
public abstract class Process<T, S> {
}
public abstract class Resource<T, S extends Process<T, S>> {
S processor;
}
public class ProcessImpl extends Process<EventType1, ProcessImpl> {
}
public class ResourceImpl extends Resource<EventType1, ProcessImpl> {
}
If you constrain the S parameter of the Resource to be a processor you also need to properly declare it on the ProcessImpl class. I don't know what EventType2 is but it should be implementing Process interface. I assumed you actually want to say ProcessImpl.
I can't see a way to edit the original version, or comment on given answers without a better rep.
This code will exist on a web layer, the eventtype2 is defined on the persistence layer and accessible only in the core layer which exists below this level.
So unfortunately without having a tight coupling, which I would like to avoid, I don't have access to EventType2.
If you don't want your code to depend on some existing package, which contains the Process, you could also introduce some new interface package depending on nothing in the very bottom of the class hierarchy. (If you are able to change the constrains of the inheritance of course.)