Codemodel does not generate static import - java

JCodeModel generates an import statement in place of an import static. For example I have a class that has import nz.co.cloudm.cloudserv.api.pojos.core.file.attachment.Attachment.Status instead of import static nz.co.cloudm.cloudserv.api.pojos.core.file.attachment.Attachment.Status so the compiler throws an error. The class Status is an inner enum that lives in the Attachment class as you can see in the import statement.
Do you know any way I can achieve an import static using code model?
Or otherwise how make the member to use the class qualified name?
private nz.co.cloudm.cloudserv.api.pojos.core.file.attachment.Attachment.Status status;

I'm not sure codemodel has the ability to define static imports, as it's an older library. You can use the enum though just through the ref() method since static imports are really just a programmer's convenience:
public class Tester {
public enum Status{
ONE, TWO;
}
public static void main(String[] args) throws JClassAlreadyExistsException, IOException {
JCodeModel codeModel = new JCodeModel();
JClass ref = codeModel.ref(Status.class);
JDefinedClass outputClass = codeModel._class("Output");
outputClass.field(JMod.PRIVATE, ref, "status", ref.staticRef(Status.ONE.name()));
codeModel.build(new StdOutCodeWriter());
}
}
Outputs:
public class Output {
private test.Tester.Status status = test.Tester.Status.ONE;
}

Related

How to use argumentcaptor to capture arguments passed to a constructor?

Say I have an outer class and an inner class set up like this:
public class OuterClass {
public static class InnerClass {
private String data; //no getter exists
public InnerClass(String arg) {
data = arg;
}
//...
}
public InnerClass functionUnderTest(String foo) {
return new InnerClass(foo);
}
//...
}
In order to not break other code, I cannot change the structure of the classes here. I also do not want to add a public getter to InnerClass as I feel this would break the intended encapsulation purely for testing purposes.
What I want to do is test the function functionUnderTest and make sure that the argument it is feeding to the InnerClass constructor really is foo. I have my reasons for wanting to test this.
My approach was to use an argumentcaptor from Mockito to try to capture the arguments fed to the constructor. Here is the test class I wrote:
public class OuterClassTest {
import org.junit.Before;
import org.junit.Test;
import org.junit.Assert;
import org.mockito.*;
import static org.mockito.Mockito.verify;
#Before
public void init() {
MockitoAnnotations.initMocks(this);
}
#Test
public void testFunction() {
ArgumentCaptor<String> stringArgumentCaptor = ArgumentCaptor.forClass(String.class);
OuterClass myclass = new OuterClass();
verify(myclass).new InnerClass(stringArgumentCaptor.capture());
String test = "haha";
myclass.functionUnderTest(test);
Assert.assertEquals(test, stringArgumentCaptor.getValue());
}
}
But there is a problem. This gives me an error: "Argument passed to verify() is of type OuterClass and is not a mock!"
I don't want to use a mock for this though, because what is the point of mocking the class and thereby the function that I'm trying to test.
I believe that because InnerClass is public and static, I don't need the OuterClass object myclass to call new InnerClass(...). But I don't really know how else to capture the arguments fed to the InnerClass constructor by myclass.functionUnderTest(). Is there a way to do this with argumentcaptor?

Static import or plain import of a static nested class

I know that the traditional import statement is for classes and the import static statement is for static members. But what should you use for static nested classes?
Consider:
public class MyUtilityClass {
public static class SomeNestedClass {
//...
}
public static class AnotherNestedClass {
//...
}
}
With usage:
import MyUtilityClass.AnotherNestedClass;
import static MyUtilityClass.SomeNestedClass;
public class Main {
public static void main(String[] args) {
SomeNestedClass a = new SomeNestedClass();
AnotherNestedClass b = new AnotherNestedClass();
}
}
You see, both import and import static statements can be used. But which one is more correct, or more typical, or recommended by most coding guidelines?
As general best practice, static import should be used for Members, and import for Classes.
From the java documentation for static import:
Where the normal import declaration imports classes from packages, allowing them to be used without package qualification, the static import declaration imports static members from classes, allowing them to be used without class qualification.

Static import and class file generation

If we use static import for a class, will the compiler generate a class file for statically imported class when compiling the actual class?
Ex:
import static com.x.y.util.B.getIds();
public class A {
...
}
When compiler compiles class A, will it generate class files for B as well?
When you use some type in class using key word import or just by full name to it. You must assure that during compilation time, compiler has that both classes in build path.
The static import allow you to access static members of imported class. Nothing more.
class Bar {
public static int getID() {
return -1;
}
}
And for static import
import static Bar.getID;
class Foo {
private void foo() {
int id = getID(); //instead of Bar.getID();
}
}
Read more on Oracle docs
No, import statement does not cause compiler to generate anything. Think about it: how can compiler generate class if it does not have a source code? Compiler by definition translate source code into executable code (or byte code in case of java).
BTW the syntax of static import in your example is not correct. You should not use () in static import:
import static com.x.y.util.B.getIds;

How To Properly Import Methods

I am currently working on understanding how to import other classes from a certain package in Java to another package and that certain class.
I was wondering how would I import a method from a certain class in Java to another one since I obviously can't "extend" that class to gain that method since its in some other package.
Example:
package Responses;
public class Hello {
public static void sayHello() {
System.out.print("HELLO!");
}
}
The question:
How do you import sayHello from the Hello class that's in package Responses.
package Start;
public class Begin {
public static void main(String[] args) {
sayHello();
}
}
I am not extending any classes like I stated above, so please don't suggest that.
Import the class that the function resides in:
import Responses.Hello;
Then you can call the function: Hello.sayHello();
In Java there is no construct to directly import a method, but you can import the class in which it resides.
import static Responses.Hello.sayHello;
Then in your other class you can do:
sayHello();
Note: You can only import methods if they are static.
You either import whole classes (A) or their static members (B).
A:
import responses.Hello;
public class Begin {
String myString = Hello.sayHello();
}
B:
import static responses.Hello.sayHello; // To import all static members use responses.Hello.*;
public class Begin {
String myString = sayHello();
}
What oracle says about the usage of static imports:
So when should you use static import? Very sparingly! Only use it when you'd otherwise be tempted to declare local copies of constants, or to abuse inheritance (the Constant Interface Antipattern). In other words, use it when you require frequent access to static members from one or two classes. If you overuse the static import feature, it can make your program unreadable and unmaintainable, polluting its namespace with all the static members you import. Readers of your code (including you, a few months after you wrote it) will not know which class a static member comes from. Importing all of the static members from a class can be particularly harmful to readability; if you need only one or two members, import them individually. Used appropriately, static import can make your program more readable, by removing the boilerplate of repetition of class names.
Find the whole thing here.
PS
Please use naming convention for your packages:
Package names are written in all lower case to avoid conflict with the names of classes or interfaces.
That's from here
One way is to make your sayHello() method public static. Like
public class Hello {
public static void sayHello() {
System.out.print("HELLO!");
}
}
Then in your Begin class, you can call sayHello using Hello. Of course you should import that Hello class first if they are not under the same package.
public static void main(String[] args) {
Hello.sayHello();
}

No error on import static Singleton in java

I have followed Singleton:
public class GameConfig {
private static GameConfig mGameConfig = null;
private String mStr = "Boo";
public static GameConfig getInstance(){
if(mGameConfig == null){
mGameConfig = new GameConfig();
}
return mGameConfig;
}
private GameConfig(){}
public String getStr() {
return mStr;
}
}
Now I try to do some experiment:
Lets say I have other class User that goes to use this singelton:
public class User{
....
private void init(){
String str = GameConfig.getInstance().getStr();
}
}
So far so good.
I'll take above mentioned class User and add import static:
import static com.app.utils.GameConfig.getInstance; // no error, why??
public class User{
....
private void init(){
String str = GameConfig.getInstance().getStr();
// I can't type
// String str = getStr(); !!
// getInstance return instance
}
}
Why is there no error? Because that's valid syntax. Isn't it good for things to work?
import static com.app.utils.GameConfig.getInstance; // no error, why??
will make getInstance() available without naming the class, for instance:
GameConfig gc=getInstance();
As a side note, I'd rename the method to be more descriptive, like getGameConfig.
The Java Language specification has the answer. First, the definition of a member
A class body may contain declarations of members of the class, that
is, fields (§8.3), methods (§8.4), classes (§8.5), and interfaces
(§8.5).
A class body may also contain instance initializers (§8.6), static
initializers (§8.7), and declarations of constructors (§8.8) for the
class.
And the definition of a single static import
A single-static-import declaration imports all accessible static
members with a given simple name from a type. This makes these static
members available under their simple name in the class and interface
declarations of the compilation unit in which the single-static-import
declaration appears.
SingleStaticImportDeclaration:
import static TypeName . Identifier ;
The static method getInstance is a static member of the GameConfig class. You can therefore import it with
import static com.app.utils.GameConfig.getInstance;
If in the below
// I can't type
// String str = getStr(); !!
you meant for getStr() to be static method of GameConfig, it makes sense that it won't compile, since you haven't imported that member.
There is no error becuase the static import is valid. static imports allow to import the static content from a class. This allows to use the static variables/methods directly wihtout using the class name.
Also you cannot use getStr directly because that is not a static method.
Since it is a valid static import.So no error.
According to java static import
The static import construct allows unqualified access to static members without inheriting from the type containing the static members. Instead, the program imports the members, either individually. at
Here getInstance() is static member so it is valid import statement.

Categories

Resources