This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I have a file, main.java, and several other files in the same package. Each file is something.class, and I would like to execute them, but I'm having problems locating how to instantiate the class from a something.java file, and then execute it. I am new to java, this is only the second program I've written so please be gentle.
One of the files I'm using is startmessage.java, and here is what I've tried:
Object StartMessage = new StartMessage();
I don't even know if that's correct. Any and all help is very much appreciated.
The class files are the compiled classes.
Source code for Java classes usually go in a file named after themselves.
For example, for your startmessage class, you would use StartMessage.java.
From another file, you can import the class, and then you can instantiate it an object of that type.
For example:
package example;
import StartMessage;
public class Example {
public static void main (String args[]) {
StartMessage startMessage = new StartMessage();
}
}
Case is important.
If your file really is called startmessage.java, and you've compiled it, and you want to create and instance of it, then try:
startmessage sm = new startmessage();
You have to import the Java class you'd like to utilize throughout your code:
package <package_name>
import <location_of_class>
Like so:
package michael;
import parent.child.*; //use any method with *
Useful link on imports and packages: http://www.leepoint.net/notes-java/language/10basics/import.html
In Java, files must be named exactly after the class they contain. In most cases this is a case-sensitive rule. Check it out.
That code segment would compile (assuming you have a StartMessage class with a default constructor), but it's not necessarily correct. Generally, you will want to declare objects in the following fashion:
<type> <name> = new <type>(<args>);
By this design, your code segment would be more correct in the following form:
StartMessage message = new StartMessage();
However, because StartMessage is a subclass of Object, and variables can be named nearly anything, your original code compiles fine.
To execute a precompiled java class (.class) it should have a main method to be executed
and it can be run using command java
http://www2.cs.uic.edu/~sloan/CLASSES/java/
For the second issue, please take a look at the following tutorial:
http://docs.oracle.com/javase/tutorial/java/javaOO/index.html
Well, first thing your file name must be exactly as a class name. For e.g.: If you named the file startmessage.java then you class should look like this:
public class startmessage { }
But it is not the way to name java classes. The proper way is:
public class StartMessage {}
To instantiate a class you should do like this:
StartMessage message = new StartMessage();
If you do like this:
Object message = new StartMessage();
You won't be able to access methods of StartMessage class. The only methods will be available from the Object class.
You can instantiate your class by creating an instance (construct it). For example:
public class MyClass
{
public void myMethod1() {System.out.println("Hello from method 1");}
public void myMethod2() {System.out.println("Hello from method 2");}
}
public class Runner
{
public static void main(String[] args)
{
// declare variable of type MyClass
MyClass myInstance = new MyClass();
// now execute its methods
myInstance.myMethod1();
myInstance.myMethod2();
}
}
This will produce output in the console:
Hello from method 1
Hello from method 2
As per your example in the question, you should use StartMessage instead of Object, e.g.
StartMessage myVariable = new StartMessage();
Related
I'm trying to use the Java TreePathScanner API to determine the list of class files that will be generated from a given compilation. For example, the following source code:
public class InnerClass {
private final InnerInnerClass clazz = new InnerInnerClass();
private class InnerInnerClass {
}
}
will generate the following files:
InnerClass.class
InnerClass$1.class
InnerClass$InnerInnerClass.class
However, in my TreePathScanner subclass, visitClass is only called twice, for the InnerClass class, and the InnerInnerClass classes, but not the anonymously named class created from the new class statement. Changing the source to the following works as expected:
public class InnerClass {
private final InnerInnerClass clazz = new InnerInnerClass() { };
private class InnerInnerClass {
}
}
My tool's full source code is available here for reference, specifically ArtifactScanner.java.
Either this is a bug or a flaw in the API as there doesn't seem to be any other way to get all of the binary names that will be generated from a given compilation unit's source code. Am I missing something?
One of the JDK developers explained on this bug report that the observed behavior really is not a bug, and that the additional class files are generated as a result of the Java compiler backend which rewrites more complex language constructs into simpler ones before generating class files.
The TreePathScanner API therefore does produce the correct output in this case, and the short of it is that TreePathScanner is the wrong solution to use for my use case (determining the list of class files that will be produced) and that com.sun.source.util.TaskListener, TaskEvent, and TaskEvent.Kind, and JavaFileManager.inferBinaryName should be used instead.
Well, not sure if the question sounds a little weird but let me try to put forth the clarification :
I have a JSP page. On this JSP page, I am calling a java class defined in one of my packages under my projects. This class connects to database and access a table which has got fields namely - functionname, function class. Now I am able to retrieve in my JSP the two strings, lets say -
String funName = "ComFunctions";
String className = "funLog");
Now, I want to invoke this function using this class name i.e. basically something like - className.funName
Is it possible in Java? Actually, these functions and class names will be retrieved in a for loop, so I can't directly call using real classname but have to use strings.
Kindly suggest if there is a way or worl around or if the question is still unclear.
I tried the following approach so far but no luck -
Class c = Class.forName(className);
Object o = c.newInstance();
Method m = c.getMethod(funName, String.class); // Not sure what is supposed to be second parameter here i.e. after funName
Error - the above code gives " No class found error". And i made sure that class is there under the package. Even adding package name i.e. packge.classname didnt help and it says "Symbol not found" for package name.
Any pointers please?
Example class that I am trying to invoke -
package mypackage;
public class ComFunctions extends WDriverInitialize{
public static void main(String[] args){
}
public static void funLog(String username){
System.out.println(userName);
}
}
You need to make sure the compiled class is in the webapp's classpath (ie, WEB-INF/classes) and use the FQN (ie, add the package name). You could also make a JAR file of your classes and add that to the WEB-INF/lib folder.
Also, the extra parameter in getMethod is to fetch a method with the matching parameters (ie, in your example, one that takes a String
You're missing one piece of the puzzle, and that's the method arguments. Without it, you can't really be sure what method funName is referring to, and what arguments to pass to it.
And of course, the class needs to be in the classpath.
I'm new to Java and i want a refinement:
First of all,i am not sure if i can have 2 classes in the same file.
My question is what is each class when you see this sequence of code:
class Something {
//code here
} //end of class Something
public class SomethingElse {
//NO code here!!!
public static void main(String[] args) {
//code of main here
}//end of main
}
What's the role of the class Something Else and why there is no code inside?I know that is a very stupid question but there are some details that i don't really get and i want some help...
You can have more than one class per file, but only one class can be public and its name must match the name of the file (e.g. public MyClass in MyClass.java).
The public class of a file will be visible to the outside world, and in particular if the class has a public static main(String[] args) method, it can be used to start an application.
In your case for example, once you have compiled your file using javac, you will get files Something.class and SomethingElse.class.
Using the command java SomethingElse will tell the Java Virtual Machine to do the following:
Find the SomethingElse class, which must be in the SomethingElse.class file
call the main method, matching the signature I pasted above on this class (and putting any given argument in the args array).
You cannot call java Something because the class isn't public and doesn't have a main method. But other classes in your program (and in particular, SomethingElse, can use your Something class).
You can have just one public class per file, and the file must have the same name of the class. But you can have other private classes that just the file class will see. For example:
File Something.java
public class Something {
//Something can access SomethingElse's doSomething method.
private class SomethingElse {
public void doSomething() {
}
}
}
class SomethingToo {
}
File OtherSomething.java
public class OtherSomething {
//OtherSomething cannot access SomethingElse's doSomething method.
//But can access SomethingToo, if they are in the same package
}
You can have multiple classes defined in a same file. However there should only one class defined as public and file name will be that public class name.
In the No code here!!! you can have class variables and methods defined. Your main() is one such example.
In the above file, there are two classes SomethingElse (public) and Something. Now, this is normally done when the non-public class is called internally by the public class. Also, in the above code fragment, SomethingElse seems to be a 'driver' class. In other words, it does not have any functionality/data of its own, but is used to execute (drive) other classes (probably Something in this case)
You can have nested classes, but two separate, public classes are not allowed. Each public class should be in it's own file named the same as the class.
While it's possible to have 2 classes in the same file, its considered bad practice. Besides the decreased readability, it will eventually become difficult to find out where that class declaration actually took place. Plus, if you declare a variable relating to the class, but not the class sharing the .java name, javac will most likely have issues compiling.
If you have to do it, make sure the only place you are using the second class is within the class sharing the .java name. (E.g. only use a Something object within the SomethingElse class). Otherwise, separate all your classes into separate .java files.
Yes, you can have 2 or more classes in single Java file.
The only condition is only one class will contain main method with signature(public static void main(String[] args)).
And only one public class will be there. And with that public class name you can save your file - the file name has to match the name of the public class.
There are two classes A and B in the same package.
how to get name of the functions of class A called by class B.
Restriction is that the code of A and B cannot be modified.
You cannot use Java reflection to do static code analysis tasks like this. The reflection APIs don't provide the information that is needed.
Off the top of my head, I can think of two approaches that will work:
If you only have the ".class" files, then you can use a bytecode library such as BCEL to load the classes and traverse them to identify all of the method calls.
If you have source code, you could also use some existing Java parser library to create ASTs for your code and analyse them.
(The first approach is probably simpler if all you want is a list of class and method names.)
Reflection can be very useful, but very complicated if you don't understand it.
If you have the name of the class, and want to print the methods:
Class c = Class.forName(the_class_name);
for(Method m : c.getMethods()) {
System.out.println(m.toString());
}
If you want the name of a class given any Object:
String className = the_object.getClass().getName();
A combination of the two could look like this:
for(Method m : the_object.getClass().getMethods())
System.out.println(m.toString());
I think what you are asking for is the names of all the methods from A that B calls.
That can't really be done with reflection, mostly because Java doesn't provide any method for doing this.
The API, as always, provides more information. If you look through there, you might come up with a simple work around.
"Class of all the functions called by class A or class B" is confusing. But, If You want to get the class and function name of caller to a method detectsName described in your class A , then following code will be useful to you.
public class A {
public void detectsName() {
Throwable t = new Throwable();
StackTraceElement traceLine = t.getStackTrace()[1];
// t.printStackTrace();
String className = traceLine.getClassName();
String methodName = traceLine.getMethodName();
int lineNumber = traceLine.getLineNumber();
System.out.println(className);
System.out.println(methodName);
System.out.println(lineNumber);
}
}
If you call this method from any other class say - B, it will be detected.
public class B {
public static void main(String[] args) {
A a = new A();
a.detectsName();
}
}
Dependency Finder can do queries for this. Its approach is to generate meta data in XML and then use regexp based comparison. You may be specifically looking for feature called 'closure' with inbound reference..
I'm getting an error: The method sleep(int) is undefined for the type Thread. I thought the sleep method is in the Thread class in Java.
import java.util.Random;
public class Thread implements Runnable {
String name;
int time;
Random r = new Random();
public Thread(String s){
name = s;
time = r.nextInt(999);
}
public void run() {
try{
System.out.printf("%s is sleeping for %d\n", name, time);
Thread.sleep(time);
System.out.printf("%s is done", name);
} catch(Exception e ) {
}
}
}
You implemented your own class called Thread and try to call sleep on it, which fails, cause sleep is undefined in your class. Your class basically shadows java's Thread class.
Call your class differently (ie. MyThread or even better MyRunnable, as noted by owlstead) or call java.lang.Thread.sleep() directly.
It's not in your Thread class.
Since you named your class Thread, that's where Java will look for Thread.sleep. If you want the function that's built into Java, try java.lang.Thread.sleep(time);.
Your class name "Thread" conflicts with the Thread class in Java standard library. Change the name of your class and it will resolve everything.
The reason you're getting this is that you've implemented your own Thread class. In your class there is no sleep method.
First prize would be to avoid using class names that are part of the standard Java libraries.
If you insists to keep the names, use java.lang.Thread.sleep(...) to specify that you want the Thread class that Java provides.
Fully-qualify Thread since you're trying to use java.lang.Thread, not your own.
The problem is that your class is named Thread, which doesn't have a sleep() method. The sleep method is in java.lana.Thread, which is being hidden by your class.
Answers to this question have already been posted yet one another analogy. It may not be the direct answer but may help you remove your confusion why should avoid reusing the names of platform classes, and never reuse class names from java.lang, because these names are automatically imported everywhere.
Programmers are used to seeing these names in their unqualified form and
naturally assume that these names refer to the familiar classes from java.lang. If
you reuse one of these names, the unqualified name will refer to the new definition
any time it is used inside its own package.
One name can be used to refer to multiple classes in different packages. The following simple code snippet explores what happens when you reuse a platform class name. What do you
think it does? Look at it. It reuses the String class from the java.lang package. Give it a try.
package test;
final class String
{
private final java.lang.String s;
public String(java.lang.String s)
{
this.s = s;
}
#Override
public java.lang.String toString()
{
return s;
}
}
final public class Main
{
public static void main(String[] args)
{
String s = new String("Hello world");
System.out.println(s);
}
}
This program looks simple enough, if a bit repulsive. The class String in the
unnamed package is simply a wrapper for a java.lang.String instance. It seems
the program should print Hello world. If you tried to run the program, though,
you found that you could not. The VM emits an error message something like this:
Exception in thread "main" java.lang.NoSuchMethodError: main
If you're using the NetBeans IDE, the program would simply be prevented from running. You would receive the message No main classes found.
The VM can’t find the main method because it isn’t there. Although
Main has a method named main, it has the wrong signature. A main method
must accept a single argument that is an array of strings. What the
VM is struggling to tell us is that Main.main accepts an array of our String
class, which has nothing whatsoever to do with java.lang.String.
Conclusion : As mentioned above, always avoid reusing platform class names from the java.lang package.