105

I'm working on a project and one requirement is if the 2nd argument for the main method starts with “/” (for linux) it should consider it as an absolute path (not a problem), but if it doesn't start with “/”, it should get the current working path of the class and append to it the given argument.

I can get the class name in several ways: System.getProperty("java.class.path"), new File(".") and getCanonicalPath(), and so on...

The problem is, this only gives me the directory in which the packages are stored - i.e. if I have a class stored in ".../project/this/is/package/name", it would only give me "/project/" and ignores the package name where the actual .class files lives.

Any suggestions?

EDIT: Here's the explanation, taken from the exercise description

sourcedir can be either absolute (starting with “/”) or relative to where we run the program from

sourcedir is a given argument for the main method. how can I find that path?

nabster
  • 1,561
  • 2
  • 20
  • 32
La bla bla
  • 8,558
  • 13
  • 60
  • 109
  • 2
    What will you do if the code is packaged in a JAR (or is otherwise not in a folder/file structure like you're assuming)? It's a dangerous assumption; this might work fine for a small experiment, class assignment, or other disposable situation, but PLEASE don't get into the habit of making that assumption for production-quality code. – E-Riz Mar 15 '12 at 22:56
  • There is no sense in finding the path to the class file. Also the exercise description does not mention that if you read it carefully (*where we run the program from* means the current path from which the program is called by the user). – The Nail Mar 15 '12 at 23:15
  • Maybe you could help me to better understand the requirement? I need to check the argument starts with a '/' (mention in the description). if it does, just use it as absolute. as is. but if it doesn't, how should I treat it? – La bla bla Mar 15 '12 at 23:18

4 Answers4

196

Use this.getClass().getCanonicalName() to get the full class name.

Note that a package / class name ("a.b.C") is different from the path of the .class files (a/b/C.class), and that using the package name / class name to derive a path is typically bad practice. Sets of class files / packages can be in multiple different class paths, which can be directories or jar files.

The Nail
  • 8,355
  • 2
  • 35
  • 48
34

There is a class, Class, that can do this:

Class c = Class.forName("MyClass"); // if you want to specify a class
Class c = this.getClass();          // if you want to use the current class

System.out.println("Package: "+c.getPackage()+"\nClass: "+c.getSimpleName()+"\nFull Identifier: "+c.getName());

If c represented the class MyClass in the package mypackage, the above code would print:

Package: mypackage
Class: MyClass
Full Identifier: mypackage.MyClass

You can take this information and modify it for whatever you need, or go check the API for more information.

Jon Egeland
  • 12,470
  • 8
  • 47
  • 62
  • 1
    Note that Class.forName("MyClass") will only work if it is in the default package (i.e. has no package declaration). – The Nail Mar 15 '12 at 22:46
  • 2
    @TheNail true, and `getName()` returns the package name along with the class name, editing now. – Jon Egeland Mar 15 '12 at 22:47
  • Use `getSimpleName()` to get only the class name without package name. – The Nail Mar 15 '12 at 22:48
  • 1
    Instead of `Class.forName("MyClass")` you should use `MyClass.class` unless you really need runtime discovery for some other reason. – mjaggard Dec 04 '15 at 13:46
15

The fully-qualified name is opbtained as follows:

String fqn = YourClass.class.getName();

But you need to read a classpath resource. So use

InputStream in = YourClass.getResourceAsStream("resource.txt");
Bozho
  • 588,226
  • 146
  • 1,060
  • 1,140
7

use this.getClass().getName() to get packageName.className and use this.getClass().getSimpleName() to get only class name

Suraj Rao
  • 29,388
  • 11
  • 94
  • 103