I want to know if i can link and compile source code file with an object file of a class without including class source files.
Or
Like in Java i can give a compiled *.class file to a friend and the doc of that class without giving the source code and he can include that class for his need without knowing the real source.
Can i do the exact thing with C++ ? and How ?
FYI:I'm using MinGW.
I'm quite new to so this may look like a dumb question (but still there's no dumb questions).
In C++ you can just produce an executable file (.exe in windows, usually no extension in Linux) or a library file (.lib or .a) or a shared libarary (.dll or .so) depending on what you want to achieve.
If you are providing a library, you will have to provide a header file with the class declarations as well. If you don't want to give out too much about the details, you can have a "implementation" class that is simply a pointer to the implementation in your header file, and the real implementation is only available to you as the owner of the sources.
For more information, you should look up "PIMPL" as Thomas Matthews suggested - that's short for "Pointer to IMPLementation class". Basically, your "public" class is just a shell providing the functions you want others to see, and the implementation class inside it does all the hard work.
Simple example
In your header file:
// Forward declaration of the implementation class.
class double_it_impl;
// Class that stores an integer, and doubles it each time you
// call doubling().
class Public_double_it
{
public:
public_double_it(int x); // COnstructor.
int doubling(); // Function d
private:
double_it_impl *pImpl;
};
In your source or private header file, we declare the actual implementation:
class double_it_impl
{
public:
double_it_impl(int x) : m_x = x; {};
int doubling() { m_x *= 2; return m_x; }
}
public_double_it::public_double_it(int x)
{
pImpl = new public_double_it(x);
}
int public_double_it::doubling()
{
return pImpl->doubling();
}
Now you can't see what the implementation class contains or how it works - of course, this is a very trivial example, but I hope it conveys the idea.
You can give them the *.class but they can be decompiled.
Most libraries are provide using the classes and the generated Javadoc.
You could compile the class into a library or dll or shared library and give to your friend.
They would need a header file that defines the interface.
See also PIMPL idiom.
Yes, you can provide a compiled object file and documentation and others can link the .o (or .obj) file into their code. The exact details of how to do this vary between compilers and development environments. If you are using g++, you simply use the following command-line:
g++ -c source.cpp
This will create a .o file which you (or anyone else) can then link with other .o files with
g++ main.o source.o
Other compilers will have similar options. Read the help files and other documentation for instructions about how to create object files.
For a large number of functions and/or classes, you should look at creating a library file. These can be statically or dynamically linked. I suggest that you search the Web for more information if you want to learn about how to create your own library files.
Related
I have a class with an existing import:
import org.packageA.Peeler
public class Potato {
Peeler peeler = new Peeler();
}
I'd like to be able to copy this class or create an object with it but change "import org.packageA.Peeler" to "import org.packZ.Peeler".
Is this possible to do dynamically?
No.
import statements are a bit of a misnomer. import com.foo.A; means: Anytime I write just A in this source file, imagine I wrote com.foo.A and that is all it means. It does not mean: Initialize this class or parse this source file or any other such thing (which is usually what import means in other environments).
Thus, what you're asking is: Can I take class Potato { org.packA.Peeler peeler = new org.packA.Peeler(); } and somehow dynamically create a different Potato class that is as if I wrote class Potato { org.packA.Peeler peeler = new org.packA.Peeler(); } - to which the answer is no; org.packA.Peeler is as related to org.packZ.Peeler as guns and grandmas (i.e.: That they have the same name is immaterial).
Even if you could, what would that mean? Java is statically and nominally typed, it wouldn't be possible to write code that refers to this rewritten potato class without using reflection or dynamic code generation which, in java at any rate, are almost always the wrong answer.
Some exotic options you do have:
Use a regexp or build script plugin to make a source file with some renames applied and include it in the build and compilation process (bad idea, but I guess you can do that)
Use ASM, BCEL or some other classfile tool to create a new class file in byte array form with renames applied, have a custom classloader that dynamically loads this, and then generate bytecode that uses this, or use reflective access. This is extremely convoluted, requires a ton of code, and is almost useless.
Perhaps take a step back and explain the problem you have that made you think: I know! I'll dynamically rewrite this class to use a different package! But I don't know how so I'll ask SO - except you're asking the wrong question, ask about your original problem.
Coming from a C++ environment I got used to splitting up many of the functions that I needed into an funcs.h file and then do #include "funcs.h" and then adding the functions prototypes into the main .cpp file.
Now I am starting to work with Java (mainly with Minecraft ModloeaderMp), and I already made a funcs.java file where there are some premade functions (e.g., some functions for file copying, giving stacks of items, etc.). Since I am already using the statement Public class mod_mine extends BaseModMp, is there a way I can import the functions or do I can I just do another Public class mod_mine extends funcs?
You don't #include in Java; you import package.Class. Since Java 6 (or was it 5?), you can also import static package.Class.staticMethodOfClass, which would achieve some forms of what you're trying to do.
Also, as #duffymo noted, import only saves you from systematically prefixing the imported class names with the package name, or the imported static method names with the package and class name. The actual #include semantics doesn't exist in Java - at all.
That said, having a "funcs.java" file seems to me like you are starting to dip your toes into some anti-patterns... And you should stay away from these.
There's no #include in Java.
I would not like a design that had a funcs.java that stored all the variables. Objects are state and behavior encapsulated into a single component. You aren't designing in an object-oriented way if you do that.
Good names matter. A class named Stuff that extends Stuff2 had better just be a poor example.
That's not good Java. I wouldn't consider it to be good C++, either.
It sounds like you're putting all your methods in the same class. You should separate them:
Utility classes
These should contain static methods that do things like get the contents of a file, show a dialog screen, or add two numbers together. They don't really belong in an object class, they don't require instances, and they're used widely throughout the program. See java.lang.Math for a good example of this.
Constant class or configuration files
This can be a Constants class that contains static final members, like PI = 3.1415. You can access them using Constants.PI.
Or, you can use configuration files and load them into Configuration and access the configuration variables with something like config.get("database").
Other
If your code doesn't fit into any of these, you will want to put it into some class such that your code fits object-oriented programming concepts. From your question, it sounds like you'll want to read up on this. I would first read Head First Java, then maybe some other books on object-oriented programming in Java. After that, I'd look at some design patterns.
Java is an object-oriented programming language, and there is a reason for it.
There isn't any #include in Java, although you can import classes from other packages.
Making separate class, func.java, to store variables might not be a good idea, until or unless all of them are constants.
By extending some class, you can reuse the function. But does extending class pass the is a test? If not that, this might be a bad idea.
If moving from C++, going through some good book, for example, Head First Java might help a lot.
There isn't any #include in Java. You can use the import statement to make classes and interfaces available in your file.
You can run the C preprocessor on a Java file, ensuring you use the -P flag to disable line annotations. A quick Google search confirms that this has been attempted at least twice, and is even used in the popular fastutil library:
Using C style macros in Java
https://lyubomyr-shaydariv.github.io/posts/2016-09-06-fun-with-java-and-c-preprocessor/
This works for all directives (#include, #define, #ifdef, and so forth) and is both syntactically and semantically identical to the equivalent statements in C/C++.
Actually... There is a way to have the same semantics as in C's #include (the keyword was later borrowed by C++ for the sake of looking fancy...). It's just not defined with the same words, but it does exactly what you are looking for.
First, let's see what you do with #include in C++ to understand the question:
include #defines,
"forward" function definitions (their "body" being defined elsewhere, in a class implementation, if you remember Turbo Pascal, you get my point),
define structures,
and that's pretty much it.
For the structure definitions, there isn't any point. That's old-school C: in C++ you don't define struct {} anymore for ages; you define class structures with properties and accessor methods. It's the same in Java: no typedef struct {} here either.
For this, you have the "interface" declaration (see Interfaces (The Java™ Tutorials > Learning the Java Language > Interfaces and Inheritance)):
It does exactly what you're looking for:
public interface MyDefines {
final CHAR_SPACE : ' '; // ugly #define
int detectSpace(FileInputStream fis); // function declaration
// and so on
}
Then, to use:
public class MyClass extends MyAncestor implements MyDefines {
...
// implementation of detectSpace()
int detectSpace(FileInputStream fis) {
int ret = 0;
char Car;
if((Car = fis.read()) != -1) && (Car == CHAR_SPACE)) ret++;
...
}
Read the link given above; it's full of useful cases.
Is there a way to obtain the Java source code from a class name?
For example, if I have access to the library with the class java.io.File, I want its source code.
I am working on a kind of parser and I need the source at execution time. I have also to search it recursively.
Say the aforementioned class has this method:
int method (User user) {...}
I would need to obtain User's source code, and so on and so forth with its inner classes.
Is there any way to obtain the java source from a class name? For example:...
You may want one of several possible solutions. Without knowing what you really want to do with the information, we can't be very precise with our recommendations, but I'd start by steering you away from source code if possible. JSE source code is available online, as are many open source libraries, but that may not always be the case. Additionally, you'll need to keep it all organized when you want to find it, much like a classpath, whereas the Class objects are much easier to get hold of, and manipulate, without having to parse text again.
Reflection
If you just need information about a class at runtime, just use the Java Reflection API. With it, given a Class object you can, for example, get the types of a specific field, list all fields and iterate over them, etc...:
Class clazz = User.class;
Field field = clazz.getDeclaredField("var");
System.out.println(field.getType().getName());
Reflection is useful for discovering information about the classes in the program, and of course you can walk the entire tree without having to find source code, or parse anything.
Remember you can lookup a class object (as long as it's on the classpath at runtime) with Class.forName("MyClass") and reflect on the resulting Class.
Bytecode Manipulation
If you need more than information, and actually want to manipulate the classes, you want bytecode manipulation. Some have tried to generate source code, compile to bytecode and load into their program, but trust me - using a solid bytecode manipulation API is far, far easier. I recommend ASM.
With it, you can not only get information about a class, but add new fields, new methods, create new classes... even load multiple variations of a class if you're feeling self-abusive. An example of using ASM can be found here.
Decompilation
If you really, really do need the source, and don't have it available, you can decompile it from a class object using one of the various decompilers out there. They use the same information and techniques as the above two, but go further and [attempt] to generate source code. Note that it doesn't always work. I recommend Jode, but a decent list, and comparison of others is available online.
File Lookup
If you have the source and really just want to look it up, maybe all you need is to put the .java files somewhere in a big tree, and retrieve based on package name as needed.
Class clazz = User.class;
String path = clazz.getPackage().getName().replaceAll("\\.","/");
File sourceFile = new File(path, clazz.getName() + ".java")
You want more logic there to check the class type, since obviously primatives don't have class definitions, and you want to handle array types differently.
You can lookup a class by name (if the .class files are on your classpath) with Class.forName("MyClass").
You can get a good approximation of the source from a class file using the JAVA decompiler of your choice. However, if you're really after the source of java.io.File then you can download that.
The best and simplest bet can be javap
hello.java
public class hello
{
public static void main(String[] args)
{
System.out.println("hello world!");
world();
}
static public void world()
{
System.out.println("I am second method");
}
}
do a javap hello and you will get this:
Compiled from "hello.java"
public class hello extends java.lang.Object{
public hello();
public static void main(java.lang.String[]);
public static void world();
}
Yes, if you download the source code. It's available for public download on the official download page.
If you're using Eclipse whenever you use the class you could right click > View Source (or simply click the class > F3) and it'll open a new tab with the source.
You can print the resource path from where the class was loaded with
URL sourceURL=obj.getClass().getProtectionDomain().getCodeSource().getLocation();
It will be a .class file , .jar,.zip, or something else.
So what you're trying to do is get the Java class at execution. For this, you need Java reflections.
If your goal is to get information about what's in a class, you may find the Java reflection API to be an easier approach. You can use reflection to look up the fields, methods, constructors, inheritance hierarchy, etc. of a class at runtime, without needing to have the source code for the class available.
Is there any way to obtain the java source from a class name?
The answer is complicated, not least because of the vagueness of your question. (Example notwithstanding).
In general it is not possible to get the real, actual Java source code for a class.
If you have (for example) a ZIP or JAR file containing the source code for the classes, then it is simple to extract the relevant source file based on the classes fully qualified name. But you have to have gotten those ZIP / JAR files from somewhere in the first place.
If you are only interested in method signatures, attribute names and types and so on, then much of this information is available at runtime using the Java reflection APIs. However, it depends on whether the classes were compiled with debug information (see the -g option to the javac compiler) how much will be available. And this is nowhere like the information that you can get from the real source code.
A decompiler may be able to generate compilable source code for a class from the bytecode files. But the decompiled code will look nothing like the original source code.
I guess, if you have a URL for a website populated with the javadocs for the classes, you could go from a class name, method name, or public attribute name to the corresponding javadoc URL at runtime. You could possibly even "screen scrape" the descriptions out of the javadocs. But once again, this is not the real source code.
I would like to be able to do something like (psuedo-code):
if (classAvailable) {
// do a thing
} else {
// do a different thing
}
What would be even better is if I could extend a class from ClassA if it's available or ClassB, if it isn't. I suspect this isn't possible though.
You can do the first part:
try {
Class.forName("my.ClassName");
// It is available
}
catch (ClassNotFoundException exception) {
// It is not available
}
My usual approach to this is:
Separate out the code which uses the optional library into a different source directory. It should implement interfaces and generally depend upon the main source directory.
In order to enforce dependencies in the build, compile the main source directory without the optional library, and then the source that depends on the optional library (with other class file from other source directory and the library on the compiler classpath).
The main source should attempt to load a single root class in the optional source directory dynamically (Class.forName, asSubclass, getConstructor, newInstance). The root class' static intialiser should check that the library is really available and throw an exception if it is not. If the root class fails to load, then possibly follow the Null Object pattern.
I don't think there's a way to dynamically choose whether to extend one class or another, except if you made a program that can manipulate bytecode directly (simple example: hold the compiled bytecode for both versions of the subclass as strings, and just use a ClassLoader to load whichever one corresponds to the superclass you have available).
You could do it in Python, though ;-)
In case you are using Spring, try to use org.springframework.util.ClassUtils#isPresent
I have a Java assignment that uses components to build program. The teacher gave us a JAR we are to use to build the calculator using Eclipse. The JAR has 2 classes. We must import the JAR and use its classes.
I import the JAR:
import SWEB401_HW1.NumericOperation;
but when I try to create an object for the class, it gives me an error because the constructor is not visible. What can I do to use the class "NumericOperation" to build the calculator?
With the information you provided - and considering that this is an assignment - I can only give you a few hints about what to look for.
Assuming your project is set up correctly, and you still cannot create instances of NumericOperation, ...
... there could be static factory methods in NumericOperation.
... the "other class" could act as factory for NumericOperation instances
... NumericOperation could actually be an interface or abstract class that you need to implement
EDIT:
Don't want to give it all away, so I'll keep this vague. As NumericOperation indeed seems to be an abstract class, try writing a class like the following and see what you must do to stop the IDE complaining:
public class MyNumericOperation extends NumericOperation {}
You can also have a look at the inheritance part of the Java Tutorial here.
If the constructor is not visible, then you are trying to invoke a non-public constructor. Look at the code or java doc for your NumericOperation class and find a constructor that is public. Most likely you're invoking the no-argument constructor and the class has specifically hidden it because you need an initial value.
For instance:
public class MyClass {
private MyClass() {
// Don't let callers instantiate me without args!
}
public MyClass(int initialValue) {
// create a new object with initialValue
}
}
If calling code attempts this:
MyClass obj = new MyClass();
You'll get the error you've posted. You need to call new MyClass(int) instead.
If the error you get is saying that the onstructor is not "visible", then it's talking about visibility in java (public, provate, protected and package).
This is good - it means that you have sucessfuly imported the class and that it's on your classpath. Ignore all the other answers that talk about fooling with your classpath - eclipse is taking care of it for you ok.
At a guess, your teacher f*cked up has not put a "public" declaration on the constructor you need to use.
To fix this, your class that you are writing needs to be in the SWEB401_HW1 package.
The easiest way in eclipse to do this is to right-click the java file in the navigator and to "refactor" it by "moving" it into package SWEB401_HW1.
If I understand your question correctly, you do not need to import anything. That's not how you access classes in a JAR file. Instead you need to add the path of the JAR file to Java's classpath; how exactly you do that depends on your operating system. Alternatively, you could extract the JAR file into the directory where your own program's class file is. A JAR file is just a ZIP file with a different extension, so you can extract it using whatever you normally use to open ZIP files, or you can use the jar tool included with the JDK:
jar xf SWEB301_HW1.jar
There's no need to extract anything. You need to use the JAR in your project by adding it to the classpath.
Are you using Eclipse? If so, you can go to the project properties -> java build path -> libraries -> add external JARs -> search for your jars and add them.
That way you'll get all the JAR classes in your project.
If the instructor gave you Javadocs, an API listing, or the source look for things like this:
public static NumericOperation ()
public NumericOperation()
public NumericOperation ()
The first one could be in any class, but would likely be in the NumericOperation class.
The second one would be a constructor in the NumericOperation class that takes parameters. Remember that if the class provides a constructor the compiler does not generate an no-argument one for you.
The last one would be in another class (since you need an instance to call the method).
In the future posting the exact error message that the compiler spit out is more helpful than an rough statement of what it said.
In agreement with some earlier answers, you need to have the jar available via the classpath, so when you run or compile do
java(c) -cp myjar.jar:. etc
I usually include the current directory so that it doesn't forget that my code is in the path.
When you import, you must use the java package names. Open the jar in a zip program and file the path to the class files you need, then put "import path;" where you replace the folder separators by '.'