#Define in Java

#define in Java

No, because there's no precompiler. However, in your case you could achieve the same thing as follows:

class MyClass
{
private static final int PROTEINS = 0;

...

MyArray[] foo = new MyArray[PROTEINS];

}

The compiler will notice that PROTEINS can never, ever change and so will inline it, which is more or less what you want.

Note that the access modifier on the constant is unimportant here, so it could be public or protected instead of private, if you wanted to reuse the same constant across multiple classes.

Equivalent of #define in Java?

As other have said, there is no such thing as #define/#ifdef in Java. But regarding your problem of having optional external libraries, which you would use, if present, and not use if not, using proxy classes might be an option (if the library interfaces aren't too big).

I had to do this once for the Mac OS X specific extensions for AWT/Swing (found in com.apple.eawt.*). The classes are, of course, only on the class-path if the application is running on Mac OS. To be able to use them but still allow the same app to be used on other platforms, I wrote simple proxy classes, which just offered the same methods as the original EAWT classes. Internally, the proxies used some reflection to determine if the real classes were on the class-path and would pass through all method calls. By using the java.lang.reflect.Proxy class, you can even create and pass around objects of a type defined in the external library, without having it available at compile time.

For example, the proxy for com.apple.eawt.ApplicationListener looked like this:

public class ApplicationListener {

private static Class<?> nativeClass;

static Class<?> getNativeClass() {
try {
if (ApplicationListener.nativeClass == null) {
ApplicationListener.nativeClass = Class.forName("com.apple.eawt.ApplicationListener");
}

return ApplicationListener.nativeClass;
} catch (ClassNotFoundException ex) {
throw new RuntimeException("This system does not support the Apple EAWT!", ex);
}
}

private Object nativeObject;

public ApplicationListener() {
Class<?> nativeClass = ApplicationListener.getNativeClass();

this.nativeObject = Proxy.newProxyInstance(nativeClass.getClassLoader(), new Class<?>[] {
nativeClass
}, new InvocationHandler() {

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String methodName = method.getName();

ApplicationEvent event = new ApplicationEvent(args[0]);

if (methodName.equals("handleReOpenApplication")) {
ApplicationListener.this.handleReOpenApplication(event);
} else if (methodName.equals("handleQuit")) {
ApplicationListener.this.handleQuit(event);
} else if (methodName.equals("handlePrintFile")) {
ApplicationListener.this.handlePrintFile(event);
} else if (methodName.equals("handlePreferences")) {
ApplicationListener.this.handlePreferences(event);
} else if (methodName.equals("handleOpenFile")) {
ApplicationListener.this.handleOpenFile(event);
} else if (methodName.equals("handleOpenApplication")) {
ApplicationListener.this.handleOpenApplication(event);
} else if (methodName.equals("handleAbout")) {
ApplicationListener.this.handleAbout(event);
}

return null;
}

});
}

Object getNativeObject() {
return this.nativeObject;
}

// followed by abstract definitions of all handle...(ApplicationEvent) methods

}

All this only makes sense, if you need just a few classes from an external library, because you have to do everything via reflection at runtime. For larger libraries, you probably would need some way to automate the generation of the proxies. But then, if you really are that dependent on a large external library, you should just require it at compile time.

Comment by Peter Lawrey: (Sorry to edit, its very hard to put code into a comment)

The follow example is generic by method so you don't need to know all the methods involved. You can also make this generic by class so you only need one InvocationHandler class coded to cover all cases.

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String methodName = method.getName();
ApplicationEvent event = new ApplicationEvent(args[0]);
Method method = ApplicationListener.class.getMethod(methodName, ApplicationEvent.class);
return method.invoke(ApplicationListener.this, event);
}

#define using in java/android studio

Java does not have #define; or any other kind of macro support; as it
does not even have the concept of pre processing.

Given your comments: first of all, you really want to step back. You don't learn Java by applying your C knowledge. Period. There is many existing documentation out there that summarizes the important differences between C and Java; you start by searching and reading such stuff.

Then: the real difference is that Java is a (heavily, but not 100%) object oriented programming language; and C is not. So you not only change syntax elements; you apply different concepts. One first starting point here would be the SOLID principles.

And then there are subtle things, such as Java coding style guides - that instruct for simple things as "no _ chars in variable names" (except for SOME_CONSTANT).

And regarding your example, a simple example would look like:

public class Class {
private final static int MAX_COUNT_OF_STUDENTS = 50;

private int numberOfStudents;
private int numberOfBooks;

public void setNumberOfStudents(int newCount) {
numberOfStudents = newCount;
}

public boolean isFull() {
return ( numberOfStudents <= MAX_COUNT_OF_STUDENTS );
}
...

That is how you would approach such things in Java. There key thing is to design classes that represent the objects in the real world you intend to model; to add the required behavior as methods.

And beyond that: even in the C world I would be really really cautious about using #defines this way. Yes, they are convenient and have their place; but using them just to safe typing word like in your example I would consider a bad practice.

What is the difference between declaration and definition in Java?

The conceptual difference is simple:

  • Declaration: You are declaring that something exists, such as a class, function or variable. You don't say anything about what that class or function looks like, you just say that it exists.

  • Definition: You define how something is implemented, such as a class, function or variable, i.e. you say what it actually is.

In Java, there is little difference between the two, and formally speaking, a declaration includes not only the identifier, but also it's definition. Here is how I personally interpret the terms in detail:

  • Classes: Java doesn't really separate declarations and definitions as C++ does (in header and cpp files). You define them at the point where you declare them.

  • Functions: When you're writing an interface (or an abstract class), you could say that you're declaring a function, without defining it. Ordinary functions however, are always defined right where they are declared. See the body of the function as its definition if you like.

  • Variables: A variable declaration could look like this:

    int x;

    (you're declaring that a variable x exists and has type int) either if it's a local variable or member field. In Java, there's no information left about x to define, except possible what values it shall hold, which is determined by the assignments to it.

Here's a rough summary of how I use the terms:

abstract class SomeClass {                // class decl.
// \
int x; // variable decl. |
// |
public abstract void someMethod(); // function decl. |
// |
public int someOtherMethod() { // function decl. |
// | class
if (Math.random() > .5) // \ | def.
return x; // | function definition |
else // | |
return -x; // / |
// |
} // |
} // /

#define directive in Java

I think I see what you're getting at; you're using #define statements as a way to define your own DSL; that is, you're writing specific statements which the compiler translates into valid syntax.

That's...not entirely possible with Java. The reason for this is Java's compilation approach is relatively set in stone.

There's likely a way around this; the main point of the code is that it has to translate to valid bytecode at some layer. If your intent is to get a DSL-like language, you could consider Groovy or Kotlin, which allow cleaner ways to express what will eventually become valid Java bytecode.

Equivalent of #define in Java for macros

If you have an array of doubles and each array element in a specific position has a definite meaning you should create a class instead.

public class MyParamBlob extends ParentParamBlob
{
private double myReadableParameter;
private double anotherParameter;
private double yetOneMore;

// getters and setters as appropriate
}

If you need to deal with an existing double[] from "outside" you could have a constructor and/or a method that takes an array as a parameter.

public class MyParamBlob
{
...
public MyParamBlob(double[] values)
{
setAll(values);
}
// getters and setters as appropriate
...
public void setAll(double[] values)
{
myReadableParameter = values[0];
anotherParameter = values[1];
// etc.
}
}

Edit - to explain my comment

If the original parent class that this is a subclass of (the reason the double[] exists in the first place) has a getter for the array, that could be overridden in this class, building and returning the array when requested -- e.g.

public double[] getParams()
{
double[] params = new double[4];
params[0] = myReadableParameter;
params[1] = anotherParameter;
// etc.
}

If the array is directly accessible from an instance of the parent class, without a getter, e.g. myArray = parentInstance.params or double d2 = parentInstance.params[2] then (1) that's a bad design and (2) callers could change the array values out from under you parentInstance.params[1] = 0.0;

define constructors in java

You have do declare a constructor without any parameters and override toString method:

public class Students{
private String Name;
private int Grade;
private double CGPA;
public Students(String Name, int Grade, double CGPA){
this.Name = Name;
this.Grade = Grade;
this.CGPA = CGPA;
}
public Students(){ // empty constructor
}
public String getName(){
return Name;
}
public void setName(String Name){
this.Name = Name;
}
public int getGrade(){
return Grade;
}
public void setGrade(int Grade){
this.Grade = Grade;
}
public double getCGPA(){
return CGPA;
}
public void setCGPA(double CGPA){
this.CGPA = CGPA;
}

@Override
public String toString() {
return "Students{" +
"Name='" + Name + '\'' +
", Grade=" + Grade +
", CGPA=" + CGPA +
'}';
} // toString() for printing your three fields
}

how to define a variable of a class type in java when the class has extends?

When you declare a FindPath reference you don't use extends, that's used to provide bounds (limits) on the classes it is legal to use for that type parameter. (You can use extends when you have a wildcard type parameter, but that's not relevant here, see https://docs.oracle.com/javase/tutorial/extra/generics/wildcards.html)

Just say:

    private FindPath<WNode,WNodePath> findPath = new FindPath<>();

Which compiles.

Yes, WNodePath implements Comparable, transitively via Path.



Related Topics



Leave a reply



Submit