Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
I am a newbie and just learned that if I define say
package my.first.group.here;
...
then the Java files that are in this package will be placed under my/first/group/here directory.
What is the main purpose of putting some Java files in a package? Also, if I choose to adopt this, how should I group them?
Thank you
EDIT: For anyone who might have the same question again, I just found this tutorial on packages from Sun.
Let's start with the definition of a "Java package", as described in the Wikipedia article:
A Java package is a mechanism for
organizing Java classes into
namespaces similar to the modules of
Modula. Java packages can be stored in
compressed files called JAR files,
allowing classes to download faster as
a group rather than one at a time.
Programmers also typically use
packages to organize classes belonging
to the same category or providing
similar functionality.
So based on that, packages in Java are simply a mechanism used to organize classes and prevent class name collisions. You can name them anything you wish, but Sun has published some naming conventions that you should use when naming packages:
Packages
The prefix of a unique package name is
always written in all-lowercase ASCII
letters and should be one of the
top-level domain names, currently com,
edu, gov, mil, net, org, or one of the
English two-letter codes identifying
countries as specified in ISO Standard
3166, 1981.
Subsequent components of the package
name vary according to an
organization's own internal naming
conventions. Such conventions might
specify that certain directory name
components be division, department,
project, machine, or login names.
Examples:
com.sun.eng
com.apple.quicktime.v2
edu.cmu.cs.bovik.cheese
I a large application, you are bound to have two files named exactly the same (java.util.Date and java.sql.Date), especially when you start bringing in third party jars. So basically, you can use packages to ensure uniqueness.
Most importantly, in my opinion, packaging breaks down projects into meaningful segments. So my SQL package has sql-related code, and my logger package handles logging.
In addition to the namespacing mentioned in other answers, you can limit access to methods and fields based on the scope declared on that member.
Members with the public scope are freely accessible, to limit access you normally define them as private (i.e. hidden outside the class).
You can also use the protected scope to limit access to the type and its children.
There is also the default scope (a member with no qualifier has the default scope) which allows child types and types in the same package access to the member. This can be an effective way of sharing fields and methods without making them too widely available, and can help with testing.
For example the method below would be visible to all other members of the same package.
public class Foo {
int doSomething() {
return 1;
}
}
To test the method you could define another type in the same package (but probably a different source location), that type would be able to access the method.
public class FooTest {
#Test
int testDoSomething() {
Foo foo = new Foo();
assertEquals(1, foo.doSomething());
}
}
It allows the program to be composed from multiple different programs/components/libraries, so that their class names will not conflict and the components are easier to organize. See http://java.sun.com/docs/books/tutorial/java/package/index.html
In Java it's customary to name packages as reverse domain names. For example, if your company's domain is "initech.com" and you are making a program called "Gizmo", the package names are typically prefixed "com.initech.gizmo", with subpackages for different components of the program.
Packages are important for giving flexibility of classes separation. They can be used for:
separating projects
separating modules
separating application layers (business, web, dao)
further finer grained code separation
For example
com.mycompany.thisproject.thismodule.web
Could indicate the web layer of some module.
Ultimately, there are 3 core reasons we want to use packages in Java.
1) Easier Maintenance
Organizing classes into packages follows the separation of concerns principle by encapsulation and allows for better cohesion in the overall system design. Moving further, packaging-by-feature allows teams of developers to find relevant classes and interfaces for making changes, supporting vertical-slicing techniques for scaled approaches used in agile methodology. For more information, see blog post: Package your classes by Feature and not by Layers and Coding: Packaging by vertical slice.
2) Provide Package security
Packages allow external access to only public access modifiers on methods in contained classes. Using the protected or no modifier will only be accessible to classes within the same package. For more information, see post:
Which Java access modifier allows a member to be accessed only by the subclasses in other package?
3) Avoid similar naming
Similar to the namespaces of .NET, class names are contained within the scope of their containing package. This means that two mutually exclusive packages can contain classes with the same name. This is because the packages themselves have different names and therefore, the fully qualified names are different. For more information, see tutorial [Naming a Package: The Java Tutorials][3].
From the Wikipedia page on the topic:
"A Java package is a mechanism for organizing Java classes into namespaces similar to the modules of Modula. Java packages can be stored in compressed files called JAR files, allowing classes to download faster as a group rather than one at a time. Programmers also typically use packages to organize classes belonging to the same category or providing similar functionality."
also, if i choose to adopt this, how
should i group them?
This depends largely on the design pattern(s) you will employ in your project. For the most part (particularly, if you're quite new) you'll want to group them by functionality or some other logical similarity.
Other people have provided very Java-specific answers which are fine, but here's an analogy: why do you organize files into directories on your hard drive? Why not just have a flat file system with everything in one directory?
The answer, of course, is that packages provide organization. The part of the program that interfaces with the database is different than the part of the program that displays a UI to the user, so they'll be in different packages.
Like directories, it also provides a way to solve name conflicts. You can have a temp.txt in a couple different directories in the same way that you could have two classes that appear in different packages. This becomes important (1) when you start combining code with other people out there on the internet or (2) even realize how Java's classloading works.
Another important thing about packages is the protected member for access control.
Protected is somewhere between public (everyone can access) and private (only class internal can access). Things marked as protected can be accessed from within the same package or from subclasses. This means that for limited access you don't have to put everything in the same class.
Java is very exact in its implementation. It doesn't really leave room for fudging.
If everyone were to use the same package, they would have to find some "World Wide" way to ensure that no two class names ever collided.
This lets every single class ever written fit into its own "Place" that you don't have to look at if you don't want to.
You may have different "Point" objects defined in 4 different places on your system, but your class will only use the one you expect (because you import that one).
The way they ensure that everyone has their own space is to use your reverse domain, so mine is "tv.kress.bill". I own that domain--Actually I share it with my brother "tv.kress.doug" and even though we share the same domain, we can't have a collision.
If a hundred divisions in your company each develop in Java, they can do so without collision and knowing exactly how to divide it.
Systems that don't do this kind of division seem really flaky to me now. I might use them to hack together a script for something personal, but I'd feel uncomfortable developing anything big without some strict packaging going on.
For Java source files, I would like to find out:
Which classes use which other classes (fully qualified names)?
Which methods call which other methods (fully qualified names)?
What would be a reasonable way to achieve that?
EDIT:
To clarify: I want a list of source code files as input. The output should be (as specified above) which class uses which other class and which method calls which other method. I do not want to inspect other loaded classes at runtime, like when using reflection.
You need to use static analysis tool as STAN standalone mode:
The standalone application is targeted to architects and project managers who are typically not using the IDE.
Or JArchitect (available also using command line)
JArchitect is a powerful tool for static code analysis. It can provide a lot of insight into complex code bases. Using custom code queries you are able to build your own rule sets in a very comfortable way.
In the Class Browser right-click menu, JArchitect proposes to explore the graph of dependencies between members (methods + fields) of a type.
Another option is SourceTrail
The graph visualization provides a quick overview of any class, method, field, etc., of interest and all its relations. The graph is fully interactive. Use it to move through the codebase by focusing on related nodes and edges.
(source: sourcetrail.com)
Unfortunately, reflection doesn't give you all the information you need to do this.
I've done it with ASM (https://asm.ow2.io/).
It provides the ability to walk the byte code of all of your classes using the visitor pattern, including the actual method implementations, from which you can extract the references to other classes.
I'm sorry that I cannot provide the implementation, because it's proprietary.
Note that this works from your .jar files, not your sources. If you really need to work from sources, then have a look at https://github.com/javaparser . Really, though, it's better to use the byte code, since the java language changes frequently, while the byte code specification does not.
I am not sure how to get a listing, but for identifying refactoring opportunities, you might try IntelliJ IDEA. It will dull out the signature line of any methods that are not accessed in the project. It will also detect code segments that are repeated elsewhere in the project, so you can extract common code.
I have a quite complex project to migrate from C++ (Linux) to Java
Currently, the C++ version is being distributed as a shared library (.so) followed by top-level interface header class. The implementation details are fully hidden from the final user.
This question is not about porting the C++ code to Java, but rather about creating similar distribution package.
Let's assume I have a very simple 'public' class in C++, topapi.h:
class TopApi
{
public:
void do( const string& v );
}
The actual implementation is hidden from the API user. The actual project may contain another 100 files/classes do() will call.
The distribution will contain 2 files: topapi.so and topapi.h
Users will #include "topapi.h" in their code, and link their applications with topapi.so.
The questions are:
1. How can I achieve a similar effect in Java (hide the IP related code)
2. How do I show public methods to the user ( not related to code protection, just a java version of the header file above )
Check out proguard. It will at least obfuscate the jar file, which otherwise is basically human readable. It's not absolutely safe from reverse engineering, but I guess neither is an so file.
I'm not an expert with Java, but this is what we have done to protect implementations in the past.
I don't know exactly what the motivations are for a Java port, but if it is just to support a Java end user, you could consider a JNI wrapper. I guess this probably isn't the case, but I thought I would mention it.
As far as exposing interface code to the user, you could write a Java interface class (like a pure virtual abstract c++ class) and simply not proguard that class.
To answer the question of how to show public methods to the user. This is usually done through a combination of declaring the internal classes without an access modifier, which makes them only accessible from within the same package, and not documenting them. Don't depend on the former though, it's easily circumventable, but it sends the message to the user that those classes are internal.
Java 9 adds modules which allow you to encapsulate entire packages, but it's not here yet, and you would still be able to circumvent the encapsulation.
One side effect of ahead of time compilation (usually the case with C++) is that the distributed code is already optimized, and contains no metadata, so it's harder to reverse engineer. Java is distributed in an intermediate language, but the actual machine code is generated at runtime (JIT compilation). The intermediate language is practically un-optimized, so it's easier to reverse engineer. Java also merges the idea of header files and source files where a .class file will contain all the metadata you need to use it.
In Android, a lot of functionality is in the Activity derived class. When an activity gets big (with many event handlers and such), the Java file can get large and very cluttered.
Is there a way to "break up" a Java class code file, like C# has the partial keyword?
As others have pointed out, you cannot split the actual file (I view this as a good thing).
You can extract view related functionality in custom views and fragments. Everything else (business logic, Web service access, DB access, etc.) can be in 'helper' classes you use in your activity. Even though activities are the God objects in Android, you don't have to write everything inside the actual activity class. It should only coordinate stuff and implement necessary callbacks and event handlers (which technically can be in their own classes as well).
short answer ? no.
quoted from wikipedia
The Sun Microsystems Java compiler requires that a source file name must match the only public class inside it, while C# allows multiple public classes in the same file, and puts no restrictions on the file name. C# 2.0 and later allows splitting a class definition into several files by using the partial keyword in the source code. In Java, a public class will always be in its own source file. In C#, source code files and logical units separation are not tightly related.
so while you may rework your design and relegate some code to utility classes to unclutter the code, you can not seperate the code of a single class across two files in java.
No. Java source codes can not be split across multiple files.
From the http://en.wikipedia.org/wiki/Comparison_of_Java_and_C_Sharp
The Sun Microsystems Java compiler requires that a source file name must match the only public class inside it, while C# allows multiple public classes in the same file, and puts no restrictions on the file name. C# 2.0 and later allows a class definition to be split into several files, by using the partial keyword in the source code. In Java, a public class will always be in its own source file. In C#, source code files and logical units separation are not tightly related.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
I am a newbie and just learned that if I define say
package my.first.group.here;
...
then the Java files that are in this package will be placed under my/first/group/here directory.
What is the main purpose of putting some Java files in a package? Also, if I choose to adopt this, how should I group them?
Thank you
EDIT: For anyone who might have the same question again, I just found this tutorial on packages from Sun.
Let's start with the definition of a "Java package", as described in the Wikipedia article:
A Java package is a mechanism for
organizing Java classes into
namespaces similar to the modules of
Modula. Java packages can be stored in
compressed files called JAR files,
allowing classes to download faster as
a group rather than one at a time.
Programmers also typically use
packages to organize classes belonging
to the same category or providing
similar functionality.
So based on that, packages in Java are simply a mechanism used to organize classes and prevent class name collisions. You can name them anything you wish, but Sun has published some naming conventions that you should use when naming packages:
Packages
The prefix of a unique package name is
always written in all-lowercase ASCII
letters and should be one of the
top-level domain names, currently com,
edu, gov, mil, net, org, or one of the
English two-letter codes identifying
countries as specified in ISO Standard
3166, 1981.
Subsequent components of the package
name vary according to an
organization's own internal naming
conventions. Such conventions might
specify that certain directory name
components be division, department,
project, machine, or login names.
Examples:
com.sun.eng
com.apple.quicktime.v2
edu.cmu.cs.bovik.cheese
I a large application, you are bound to have two files named exactly the same (java.util.Date and java.sql.Date), especially when you start bringing in third party jars. So basically, you can use packages to ensure uniqueness.
Most importantly, in my opinion, packaging breaks down projects into meaningful segments. So my SQL package has sql-related code, and my logger package handles logging.
In addition to the namespacing mentioned in other answers, you can limit access to methods and fields based on the scope declared on that member.
Members with the public scope are freely accessible, to limit access you normally define them as private (i.e. hidden outside the class).
You can also use the protected scope to limit access to the type and its children.
There is also the default scope (a member with no qualifier has the default scope) which allows child types and types in the same package access to the member. This can be an effective way of sharing fields and methods without making them too widely available, and can help with testing.
For example the method below would be visible to all other members of the same package.
public class Foo {
int doSomething() {
return 1;
}
}
To test the method you could define another type in the same package (but probably a different source location), that type would be able to access the method.
public class FooTest {
#Test
int testDoSomething() {
Foo foo = new Foo();
assertEquals(1, foo.doSomething());
}
}
It allows the program to be composed from multiple different programs/components/libraries, so that their class names will not conflict and the components are easier to organize. See http://java.sun.com/docs/books/tutorial/java/package/index.html
In Java it's customary to name packages as reverse domain names. For example, if your company's domain is "initech.com" and you are making a program called "Gizmo", the package names are typically prefixed "com.initech.gizmo", with subpackages for different components of the program.
Packages are important for giving flexibility of classes separation. They can be used for:
separating projects
separating modules
separating application layers (business, web, dao)
further finer grained code separation
For example
com.mycompany.thisproject.thismodule.web
Could indicate the web layer of some module.
Ultimately, there are 3 core reasons we want to use packages in Java.
1) Easier Maintenance
Organizing classes into packages follows the separation of concerns principle by encapsulation and allows for better cohesion in the overall system design. Moving further, packaging-by-feature allows teams of developers to find relevant classes and interfaces for making changes, supporting vertical-slicing techniques for scaled approaches used in agile methodology. For more information, see blog post: Package your classes by Feature and not by Layers and Coding: Packaging by vertical slice.
2) Provide Package security
Packages allow external access to only public access modifiers on methods in contained classes. Using the protected or no modifier will only be accessible to classes within the same package. For more information, see post:
Which Java access modifier allows a member to be accessed only by the subclasses in other package?
3) Avoid similar naming
Similar to the namespaces of .NET, class names are contained within the scope of their containing package. This means that two mutually exclusive packages can contain classes with the same name. This is because the packages themselves have different names and therefore, the fully qualified names are different. For more information, see tutorial [Naming a Package: The Java Tutorials][3].
From the Wikipedia page on the topic:
"A Java package is a mechanism for organizing Java classes into namespaces similar to the modules of Modula. Java packages can be stored in compressed files called JAR files, allowing classes to download faster as a group rather than one at a time. Programmers also typically use packages to organize classes belonging to the same category or providing similar functionality."
also, if i choose to adopt this, how
should i group them?
This depends largely on the design pattern(s) you will employ in your project. For the most part (particularly, if you're quite new) you'll want to group them by functionality or some other logical similarity.
Other people have provided very Java-specific answers which are fine, but here's an analogy: why do you organize files into directories on your hard drive? Why not just have a flat file system with everything in one directory?
The answer, of course, is that packages provide organization. The part of the program that interfaces with the database is different than the part of the program that displays a UI to the user, so they'll be in different packages.
Like directories, it also provides a way to solve name conflicts. You can have a temp.txt in a couple different directories in the same way that you could have two classes that appear in different packages. This becomes important (1) when you start combining code with other people out there on the internet or (2) even realize how Java's classloading works.
Another important thing about packages is the protected member for access control.
Protected is somewhere between public (everyone can access) and private (only class internal can access). Things marked as protected can be accessed from within the same package or from subclasses. This means that for limited access you don't have to put everything in the same class.
Java is very exact in its implementation. It doesn't really leave room for fudging.
If everyone were to use the same package, they would have to find some "World Wide" way to ensure that no two class names ever collided.
This lets every single class ever written fit into its own "Place" that you don't have to look at if you don't want to.
You may have different "Point" objects defined in 4 different places on your system, but your class will only use the one you expect (because you import that one).
The way they ensure that everyone has their own space is to use your reverse domain, so mine is "tv.kress.bill". I own that domain--Actually I share it with my brother "tv.kress.doug" and even though we share the same domain, we can't have a collision.
If a hundred divisions in your company each develop in Java, they can do so without collision and knowing exactly how to divide it.
Systems that don't do this kind of division seem really flaky to me now. I might use them to hack together a script for something personal, but I'd feel uncomfortable developing anything big without some strict packaging going on.