I am writing an administrator class that all other classes I am writing are meant to inherit from. In this case I want the classes to inherit a main method, and I am planning on implementing a factory as well. There are a few sysouts that I have to write that include various class names such as charcount, linecount and the such. For this I need to be able to get the current class name, since this method will be inherited by multiple classes. Is there a way to do this in java? You can find an example of the sysout I am looking to do below:
System.out.println("Usage: className <src>\n");
Thank you all in advance, any help is appreciated!
edit:
Hey guys!
Very sorry I wasnt clear before, I'll show the entire code below and try to further explain my idea. So what I am doing is essentially making a main method that checks to see if a file exists, and if the file exists, it will try to execute a certain function (All this will be in the command line).I am practicing factory design patterns (something I've never done before). I will use the execute part of the main method to call on some factory (not yet made) to create objects of subclasses of administrator and return things like charcount in a file and linecount in a file. The above question refers to one part of this main method that will print the usage of the subclass. So for example, I will have charcount inherit from administrator because the process of checking the file and is in the main method of administrator, however when I print the usage message, I dont want it to print "Usage: Administrator ", but "Usage: charcount ". I hope that clears things up, and sorry again for how badly I explained it above, you can find what I have so far as code below:
public class Administrator
{
private static File srcFile = null;
private static String srcFilename = "<srcFilename>";
public static void main(String[] args) throws IOException
{
//check the command line
if(args.length != 1)
{
System.out.println("Usage: charcount <src>\n");
return;
}
// Check if arguments are valid, if the srcFile exists, and if can create the dstFile.
if (args[0] != null)
{
//check <src>
srcFilename = args[0];
System.out.println( ": srcFilename '" + srcFilename + "'");
srcFile = new File(srcFilename);
if(!srcFile.canRead())
{
System.out.println("charcount: cannot open srcFile '" + srcFilename + "'");
return;
}
}
else
{
System.out.println("charcount: [OK] srcFilename = '" + srcFilename + "'");
}
}
public static int execute() {return 0;}
}
You can do something like this:
System.out.println("Class name: " + getClass().getName());
Which will return foo.bar.Baz (assuming your class is named Baz and in package foo.bar)
Or you can
System.out.println("Class name: " + getClass().getSimpleName());
Which will simply return 'Foo'
You might find this related question helpful: What is the difference between canonical name, simple name and class name in Java Class?
Edit: The question asks about doing this from the "main" method, which could be understood as public static void main(String[] args) or as the primary method in a given class hierarchy. Since the question goes on to discuss the method being inherited by multiple classes, I understood "main" as "primary". This answer wouldn't work from public static void main(String[] args) because getClass() is an instance method and can't be invoked from a static context.
Java Class class has some useful methods. You can use getClass().getSimpleName(). at runtime this method called based on object's type.
Try using this methods:
this.getClass().getCanonicalName() or this.getClass().getSimpleName().
If it's an anonymous class, you should use this.getClass().getSuperclass().getName()
Related
I am really new to java (started learning 2 days ago). Sorry if this is a stupid question. I am trying to learn how to use rt.exec & similar methods so I tried to make a very simple program which runs calc.exe. This is the code:
public class main {
{
try {
Runtime rt = Runtime.getRuntime() ;
Process p = rt.exec("calc.exe") ;
}
catch(Exception exc){/*handle exception*/}
}
}
I get the error " The value of local variable p is not used".
And if I try to compile this is what I get:
I think it's easy to fix but I don't know how. Would be nice if someone helped.
Well, the error "The value of local variable p is not used.", Is not actually an error. It's your IDE (Eclipse), warning you that you aren't actually reading that variable, so you aren't receiving any input from it.
And the other problem with your class is, you don't have a main method. Like this,
public class main {
public static void main(String[] args) {
try {
Runtime rt = Runtime.getRuntime() ;
Process p = rt.exec("calc.exe") ;
} catch(Exception exc){
/*handle exception*/
}
}
}
And by the way, you should always start a class name with a captial letter. So public class main, should actually be public class Main
You get that error because you don't have the main method that is used to start the java program:
public class main {
public static void main(String[] args) {
try {
Runtime rt = Runtime.getRuntime() ;
Process p = rt.exec("calc.exe") ; // here, eclipse is WARINING(so you can ignore it) you that that the variable p is never used(it's just a warning)
} catch(Exception exc) {
/*handle exception*/
// never do this, always put at least a System.out.println("some error here" + e); so you don't ignore a potential exception
}
}
I believe what you have is not an error but a warning; eclipse (and other IDEs/compilers) will tell you that, although you assigned a value to the variable p, you did not use it anywhere. It tells you this because this is sometimes an error; mostly when you assign a value to a variable, you later use that variable in some way.
You can eliminate the error by changing that particular statement to just
rt.exec("calc.exe")
since you are not required to assign a value from the call to exec.
There is no such thing as a stupid qiestion(only misplaced ones, in the worst case).
The "Editor does not contain a main type" refers to the fact that you have not defined a main method. All java programs require a main method, as such:
public static void main(String [] args){
<code>
}
This is where you must place your code.
The "Value not used" is just a warning; it tells you that your variable p only exists within the try-block. You can declare your p-variable before the try - that way, you can use it outside the try-scope(the scope of a variable refers to where it exists, in this case, only inside the try-block).
If you want to use your p, this is what you're after:
public class Main {
public static void main(String[] args) {
Process p;
try {
Runtime rt = Runtime.getRuntime();
p = rt.exec("calc.exe");
} catch(Exception exc) {/*handle exception*/}
}
}
[EDIT]: Note that it is part of the java coding convention to use Capital letters for the first letter of a class, e.g. Main.java(not main.java)
The use of the variable is not in issue here. That error appears because JVM needs a method with the signature to know where to start execution.
public static void main( String args[] ){ //TODO: Stuff here }
Introduce a method with this signature in your class, and it shall clear that error.
Alternatively, you may embed your code in a static block as below - but this method is not to be recommended.
static {
// TODO: Your code here
}
Error "The value of local variable p is not used" due to the fact that nowhere in the code, you do not use the variable p.
To remove the error - it is necessary to remove the variable "p".
To run the calculator, you must use the code:
public class MainClass {
public static void main(String args[]) throws IOException {
Runtime.getRuntime().exec("cmd /c calc.exe");
}
}
This and all other comments translated by Google Translate
you are not using main how can you compile please use main method.
Ans second one is use p local variable in your method.other wise declare p variable starting of method.
I am somewhat new to JAVA. I've been working with it in college, but I have to admit, my instructor is of absolutely no help. She hardly knows JAVA herself, but that is another issue all in itself. I've been confused as to how methods and classes work. I'm creating this program that uses two files, one "main" file, and a "test" file. I can't seem to get the "main" file correct, as the compiler keeps telling me that it cannot find the symbols, even though they are. In the "test" file, I can't seem to get the compiler to recognize the methods from the "main" file. I have made sure that the files are in the same folder. I want to combine them into one file for simplicity, but I will lose points. I've included my code so far. I'm not looking for a "fix-it" solution, I just want to figure out why it's not working. ANY help is appreciated, since my instructor isn't of much assistance Thank you kindly!
MAIN FILE:
import java.util.Scanner;
class Fruit1 {
static Scanner console = new Scanner(System.in);
public static void main(String args[]) {
String color;
String taste;
}
public Fruit1() {
// generic constructor
color = "red";
taste = "yum";
}
public Fruit1(String aColor, String aTaste) {
// constructor with parameters
color = aColor;
taste = aTaste;
}
public Fruit1(String bColor, String bTaste) {
color = bColor;
taste = bTaste;
}
String getTaste() {
return taste;
}
String getColor() {
// Accessor method
return color;
}
}
TEST FILE:
import java.util.*;
public class Fruit1Test {
static Scanner console = new Scanner(System.in);
public static void main(String args[]){
Fruit1 a = new Fruit1("pinkish-red", "sweet-tart");
Fruit1 l = new Fruit1("yellow", "tart/sour");
a.taste();
a.color();
l.taste();
l.color();
System.out.println("Your apple is " + a.color + "in color and has a " + a.taste + " taste. ");
System.out.println("Your lemon is " + l.color + "in color and has a " + l.taste + " taste. ");
System.out.println();
}
}
a.taste(); will try to find method taste(); in your main file i.e. in Fruit1.java file. However as same is not found, it will throw error at compile time only that Method taste() is not found...
All below 4 statements will FAIL as those are not present...
a.taste();
a.color();
l.taste();
l.color();
As you are creating object of class by using below statement, already values to taste and color by use of constructor public Fruit1(String aColor, String aTaste){.
Fruit1 a = new Fruit1("pinkish-red", "sweet-tart");
I believe you now want to print the values of color and taste. To print those use getter methods that you have (getColor() & getTaste())
System.out.println("Your apple is " + a.getColor() + " in color and has a " + a.getTaste() + " taste. ");
System.out.println("Your Lemon is " + l.getColor() + " in color and has a " + l.getTaste() + " taste. ");
Note
You don't need to write public Fruit1(String bColor, String bTaste){ again as you have already defined above that....
Also your below statement should be before constructor and out of psvm
String color;
String taste;
Let me know if you are unclear...
Good Luck
You never declare the fields color or taste for the object Fruit1. Instead, you created the variables in the main method.
I suggest you read some basic tutorials on Java to get the hang of things. (Oracle also provides more advanced tutorials.)
I noticed in Fruit1, you are declaring the member variables in function main(). From the looks of it, Fruit1Test should have a main() fxn but Fruit1 should not. Take out those member variables out of main() and get rid of main() in Fruit1 (put it under the 'console' variable).
I also noticed that you have 2 constructors that both take in Strings. The compiler will probably complain about that too. I don't have a compiler in front of me but that's what I can tell just from looking.
For your first problem, it seems you're misunderstanding how to declare instance fields. You're creating them inside the main function, when you should create them directly inside the class.
For your second problem, see Fahim Parkar's comment, if it applies to your case. BTW it's a good practice to always have only one class/interface/enum per file, and have the file with the same name of the class (this second part may be mandatory in Java, I don't remember for sure - it applies to public classes, but I dunno if it also applies for "default, package protected" ones).
If they're named correctly, OTOH, maybe the error is because your "main" file didn't compile, so the "test" one didn't find it...
P.S. I just noticed you have two constructors with the same signature (number of parameters and same parameter types). You must remove one.
so suppose I have a java package....
it's got the main class with the main method
and then it's got a whole bunch of other classes.....
my question is, is it possible to get the args that was passed into the main method from these other classes that are not part of the main class but in the same package...
No, not portably, there may be some trickery based on the JVM implementation but I've never seen it, and it would be a very bad idea to rely on it even if it existed.
If you want those values elsewhere, the main function needs to make them available somehow.
An easy way to do this (not necessarily the best way) is to simply store away the strings as the first thing in main and provide a means for getting at them:
Scratch2.java:
public class Scratch2 {
// Arguments and accessor for them.
private static String[] savedArgs;
public static String[] getArgs() {
return savedArgs;
}
public static void main(String[] args) {
// Save them away for later.
savedArgs = args;
// Test that other classes can get them.
CmdLineArgs cla = new CmdLineArgs();
cla.printArgs();
}
}
CmdLineArgs.java:
public class CmdLineArgs {
public void printArgs() {
String[] args = Scratch2.getArgs();
System.out.println ("Arg count is [" + args.length + "]");
for (int i = 0; i < args.length; i++) {
System.out.println ("Arg[" + i + "] is [" + args[i] + "]");
}
}
}
And, when run with the arguments a b c, this outputs:
Arg count is [3]
Arg[0] is [a]
Arg[1] is [b]
Arg[2] is [c]
The system-properties on some (?) JRE-implementations provide the system-property "sun.java.command" to get the programm-name and parameters that were used to start the program. Like "myjar.jar param1 param2 ...".
While this value doesn't even belong to the set of properties that are mentioned in the documentation, it is present in both Oracle-JRE v1.8 and OpenJRE v1.8 (tested).
I couldn't find any documentation whether this value is supported by default though (best I could find was the list in the System#getProperties() docs). Any clarification on this would be welcome. Handle with care!!!
If you don't care about OS portability, read /proc/self/cmdline or the equivalent for your OS.
See http://en.wikipedia.org/wiki/Procfs
As paxdiablo said, your main class would have to store these parameters and then either distribute or make available to needed ones. Often a good idea would be to let another class do the parsing of these parameters, and provide an object of this class instead of the raw command line to whoever needs it.
I'm kind of a newb at this, but you should be able to store the string[] args to a private instance variable, then make an accessor method for it.
E.g.,
public class test {
private String[] myArgs = new String[10];
public static void main(String[] args) {
myArgs = args;
}
public String[] getArgs() {
return myArgs;
}
}
Not sure if it will work, but that's the idea.
This is a second part to my question here.
I now have a process but I want to know how to get the output from the process?
String filename = matlab.getfileName();
Process p = Runtime.getRuntime().exec("java -cp mediaProperty.java " + filename);
My mediaProperty.java:
public class mediaProperty {
public static Object main(String[] args) {
Object[] mediaProp = null;
java.util.List lstMedia = new ArrayList();
Media media = null;
try {
media = new Media();
lstMedia.add(args);
mediaProp = media.media(3, lstMedia);
} catch (Exception p) {
System.out.println("Exception: " + p.toString());
} finally {
MWArray.disposeArray(mediaProp);
if (media != null) {
media.dispose();
}
}
return mediaProp;
}
}
The mediaProperty.java will return an Object. Inside this is actually String array. How do I get the array? And is the way I'm calling exec() correct?
use public static void main (not Object as return type)
Serialize the object using ObjectOutputStream (all necessary examples are in the javadoc)
The only thing different from the example is the construction - construct it like
ObjectOutputStream oos = new ObjectOutputStream(System.out);
in the program calling exec(), get the output with process.getOutputStream()
Read in an ObjectInputStream based on the already retreived OutputStream (check this)
Deserialize the object (see the javadoc of ObjectInputStream)
Now, this is a weird way to do it, but as I don't know exactly what you are trying to achieve, it sounds reasonable.
You could do System.setOut(new PrintStream(p.getOutputStream())) if you'd like to have the process print its results directly to standard output. Of course, this will override the old standard output. But you could also do other things with the process's output stream, like have a thread that reads from it.
A problem with your code is that the main function of a class must be of type void, and will return nothing. You will not be able to pass Java objects between processes, as they are running in different JVMs. If you must do this you could serialize the object to disk, but I imagine you don't even need to run this in a separate process.
mediaProp is a local variable in your main() method. It's not accessible from the outside.
You'll have to redesign your mediaProperty class a bit.
First, you should use:
"java -cp . mediaProperty " + filename
for calling the java process. The "-cp ." defines the classpath and I have made the assumption that the java file is compiled and the generated class file is at the same path as the executing process.
Then, you need to print the result at the standard output and not just return it. Finally, read this article for reading the output.
Tip 1: Rename the class to MediaProperty
Tip 2: Why you don't call the MediaProperty class directly from your code? Is it necessary to start a new process?
There are a few gotcha's.
In exec you assume that java is on the path, and the filename should be fully qualified or you should know that the current working dir of the java process is OK.
main() should return void (nothing). If you want to pass the results out of your program use something like:
for (Object o : mediaProp) {
System.out.println(o);
}
and parse it again on the input stream (the calling software).
Better yet, include the MediaProperty class in the java path and call main(...) directly in stead of calling a separate java process.
Okay I'll try to be direct.
I am working on a file sharing application that is based on a common Client/Serer architecture. I also have HandleClient class but that is not particularly important here.
What I wanna do is to allow users to search for a particular file that can be stored in shared folders of other users. For example, 3 users are connected with server and they all have their respective shared folders. One of them wants to do a search for a file named "Madonna" and the application should list all files containing that name and next to that file name there should be an information about user(s) that have/has a wanted file. That information can be either username or IPAddress. Here is the User class, the way it needs to be written (that's how my superiors wanted it):
import java.io.File;
import java.util.ArrayList;
import java.util.Scanner;
public class User {
public static String username;
public static String ipAddress;
public User(String username, String ipAddress) {
username = username.toLowerCase();
System.out.println(username + " " + ipAddress);
}
public static void fileList() {
Scanner userTyping = new Scanner(System.in);
String fileLocation = userTyping.nextLine();
File folder = new File(fileLocation);
File[] files = folder.listFiles();
ArrayList<String> list = new ArrayList<String>();
for (int i = 0; i < files.length; i++) {
list.add(i, files[i].toString().substring(fileLocation.length()));
System.out.println(list.get(i));
}
}
public static void main(String args[]) {
System.out.println("Insert the URL of your shared folder");
User.fileList();
}
}
This class stores attributes of a particular user (username, IPAddress) and also creates the list of files from the shared folder of that particular user. the list type is ArrayList, that's how it has to be, again, my superiors told me to.
On the other hand I need another class that is called RequestForFile(String fileName) whose purpose is to look for a certain file within ArrayLists of files from all users that are logged in at the moment of search.
This is how it should look, and this is where I especially need your help cause I get an error and I can't complete the class.
import java.util.ArrayList;
public class RequestForFile {
public RequestForFile(String fileName) {
User user = new User("Slavisha", "84.82.0.1");
ArrayList<User> listOfUsers = new ArrayList();
listOfUsers.add(user);
for (User someUser : listOfUsers) {
for (String request : User.fileList()) {
if (request.equals(fileName))
System.out.println(someUser + "has that file");
}
}
}
}
The idea is for user to look among the lists of other users and return the user(s) with a location of a wanted file.
GUI aside for now, I will get to it when I fix this problem.
Any help appreciated.
Thanks
I'm here to answer anything regarding this matter.
There are lots of problems here such as:
I don't think that this code can compile:
for (String request : User.fileList())
Because fileList() does not return anything. Then there's the question of why fileList() is static. That means that all User objects are sharing the same list. I guess that you have this becuase you are trying to test your user object from main().
I think instead you should have coded:
myUser = new User(...);
myUser.fileList()
and so fileList could not be static.
You have now explained your overall problem more clearly, but that reveals some deeper problems.
Let's start at the very top. Your request object: I think it represents one request for one user with one file definition. But it needs to go looking in the folders of many users. You add the the requesting user to a list, but what about the others. I think that this means that you need another class responsible for holding all the users.
Anyway lets have a class called UserManager.
UserMananger{
ArrayList<User> allTheUsers;
public UserManager() {
}
// methods here for adding and removing users from the list
// plus a method for doing the search
public ArrayList<FileDefinitions> findFile(request) [
// build the result
}
}
in the "line 14: for (String request : User.fileList()) {" I get this error: "void type not allowed here" and also "foreach not applicable to expression type"
You need to let User.fileList() return a List<String> and not void.
Thus, replace
public static void fileList() {
// ...
}
by
public static List<String> fileList() {
// ...
return list;
}
To learn more about basic Java programming, I can strongly recommend the Sun tutorials available in Trials Covering the Basics chapter here.
It looks like you're getting that error because the fileList() method needs to returns something that can be iterated through - which does not include void, which is what that method returns. As written, fileList is returning information to the console, which is great for your own debugging purposes, but it means that other methods can't get any of the information fileList sends to the console.
On a broader note, why is RequestForFile a separate class? If it just contains one method, you can just write it as a static method, or as a method in the class that's going to call it. Also, how will it get lists of other users? It looks like there's no way to do so as is, as you've hard-coded one user.
And looking at the answers, I'd strongly second djna's suggestion of having some class that acts as the controller/observer of all the Users.