Using pre-defined class names in java - java

I'm fairly new to Java. I learnt that the names of predefined classes in java are not keywords and thus we can use those as identifiers.
I tried out the following code: (I know that that import is redundant)
import java.lang.*;
class Process{
public Process(){
System.out.println("Constructor of Process");
}
}
public class NewMain {
public static void main(String[] args) {
Process p = new Process();
}
}
and the out put was:
Constructor of Process
However, when I replaced import java.lang.*; with import java.lang.Process;, I got an error cause it tried to instantiate the predefined Process class. I had assumed that the program will check scope by scope and will thus execute the userdefined class constructor in both cases. How am I wrong?

Related

Are java imports used professionally?

I'm currently self studying Java, and am not sure with this "import" thing. It adds classes(not sure), and has methods that would serve a different function relative on the type of class I declare from the "import"ed thing.
I'm curious if import is frequently used for work, or is this relative to the user if he/she would want to use import or not.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner ThisObject = new Scanner(System.in);
}
}
Java import is a compile time feature that allows you to omit the package name when programming. There is no byte-code import, the compiler will replace
Scanner ThisObject = new Scanner(System.in);
with
java.util.Scanner ThisObject = new java.util.Scanner(System.in);
As for how common it is, I would say extremely. However, there is another form of import called static import which allows you to bring static methods and fields from another class into your current namespace. static import is not very common. Finally, Java variable names start with a lower case letter (by convention).
import static java.lang.System.in;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner thisObject = new Scanner(in); // System.in through static import
}
}

Why can you import a class with the same name as a nested class?

Consider the following code:
import java.util.Calendar;
class Demo
{
class Calendar {}
public static void main (String[] args) {
// System.out.println(Calendar.DAY_OF_WEEK); // Would be an error.
}
}
This code compiles fine; but if you refer to Calendar within Demo, you are referring to Demo.Calendar, not java.util.Calendar.
The import is clearly redundant; but it seems strange that it is allowed, considering you're not allowed to import a class with the same simple name as a top-level class defined in the same compilation unit (per JLS Sec 7.5.1):
import java.util.Calendar; // error: Calendar is already defined in this compilation unit
class Calendar {}
Is there a practical reason why such an import as in the first code example would not be a compile-time error?
The only case I can come up with is where you have a twice (or more) -nested class with the same name as the import:
import java.util.Calendar;
class Demo {
static class Nested {
static class Calendar {}
static void useNested() {
System.out.println(Calendar.class); // Demo.Nested.Calendar
}
}
static void useImported() {
System.out.println(Calendar.class); // java.util.Calendar
}
public static void main(String[] args) {
Nested.useNested();
useImported();
}
}
Ideone demo
In this case, the nested Calendar isn't automatically visible outside the scope of the Nested class, so the imported Calendar class is used outside, e.g. in the useImported method.
I wouldn't really describe this as a "practical" use, though - it's just plain confusing as to which is used in each context, and definitely worth avoiding. It still interested me that this case exists, though.
I suppose there is another similar case:
import java.util.Calendar;
class Demo {
static void useImported() { ... }
}
class Demo2 {
class Calendar {}
static void useNested() { ... }
}
(where these classes are in the same compilation unit). Basically the same idea as above.
I suppose, if you import a class, it's visible in the global space of that compilation unit. But if you name your compilation unit or top level class the same as the import, then you are basically conflicting it with the import and hence it'll be ambiguous for JVM to know which is which. and since its compiling a class, it'll give an error for import.
Also, when it's inside another class, you are shadowing the import over there. It's just similar in the way as global/class level variables and method level variables hiding them if defined with the same name.
Hope this helps.

Java - How to invoke a method from another class, with the class name and method name as a string

This method is called regularly
public static void stynax(String N[]) {
if (N[1].equals("echo")) { echo.s(); main(); }
if (N[1].equals("detectos")) { detectos.s(); main(); }
if (N[1].equals("getuser")) { getuser.s(); main(); }
if (N[1].equals("exit")) { exit.s(); main(); }
if (N[1].equals("makefile")) { makefile.s(); main(); }
if (N[1].equals("cd")) { cd.s(); main(); }
if (N[1].equals("system")) { system.s(); main(); }
main();
}
How can I invoke all these methods
system.s();
echo.s();
Ect, by seeing if the class exists, then calling the corresponding method.
N[1] is always the class name. The class where this method is stored is in a class called main, and the classes that are called are in a different package called Commands.
I always seem to get this error, when trying to make a Class variable, i think this is the main issue.
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
So it never gets to invoke the method.
To simplify.
1) The program gets the class name as a String as N[1]
2) It sees if the class exists
3) If the class exists it calls it by the name of the class N[1].s();
Edit: Imports used
import java.io.ByteArrayOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import cgameing.Commands.FileBrowser;
import cgameing.Commands.banner;
import cgameing.Commands.cd;
import cgameing.Commands.detectos;
import cgameing.Commands.echo;
import cgameing.Commands.exit;
import cgameing.Commands.getuser;
import cgameing.Commands.makefile;
import cgameing.Commands.system;
end of edit:
This one works, for anyone wanting to do the same thing
(Class.forName("commands."+N[1])).getDeclaredMethod("s", null).invoke(null,null);
Thanks everyone
You'll need to use reflection. Try something as follows. Use fully qualified class name instead of "XYZ" if your class is in a different package.
import java.lang.reflect.*;
import java.lang.*;
public class ReflectionTest {
public static void main(String[] args)throws NoSuchMethodException,
ClassNotFoundException,
IllegalAccessException,
InvocationTargetException {
(Class.forName("XYZ")).getDeclaredMethod("ABC", null).invoke(null,null);
}
}
class XYZ
{
public static void ABC()
{
System.out.println("Lulz");
}
}
For your use case given your classes are in commands package (as you stated in a comment). The fully qualified name will then be commands.classname
(Class.forName("commands."+N[1])).getDeclaredMethod("s", null).invoke(null,null);
You can use Reflection.
You have Class name coming in Array.
You can use "Class" and "Method" class. Class can determine if the class exists or not, and method can be used to call method you need to call.
try {
Class<?> c = Class.forName(N[1]);
Object t = c.newInstance();
Method[] allMethods = c.getDeclaredMethods();
for (Method m : allMethods) {
String mname = m.getName();
// if name matches use invoke method.
}
} catch (ClassNotFoundException x) {
//handle exception
}
Please consult API if you need to see more details.
I recommend you avoid using reflection if you possibly can. Better is to define the commands you expect to see - ideally in an enum.
For example:
enum Command {
CD(FileSystem::cd),
EXIT(Application::exit),
MAKEFILE(FileSystem::createFile),
...
private final Runnable runnable;
Command(Runnable runnable) {
this.runnable = runnable;
}
public void run() {
runnable.run();
}
}
You can still use the name to get the command if you wish (automatically throwing an exception if the value isn't found in the enum - which is presumably what you would want):
Command.valueOf(commandString.toUpperCase()).run();
Or call the commands directly without having to know which method they delegate to:
Command.MAKEFILE.run();
Given you are going to have a list of if statements somewhere, you might as well encapsulate that in an enum which is much more explicit than embedding the method names.
Okay, everyone seems to suggest reflection, there is at least one alternative way to do it, depending on whether you know your class and method names at compile time or not.
So, lets say we have this method in someclass:
public void changeDirectory(String args) {
//do something
}
If they are known, you could easily use method references:
HashMap<String, Consumer<String[]>> commands = new HashMap<>();
commands.put("cd", SomeClass::changeDirectory);
commands.get("cd").accept(args);
The drawback would be, the method signature would have to be the same... on the other hand, if you know the exact method anyway, you could just use a switch statement and call them directly...
If you want to do it dynamically, the alternative to reflection would be MethodHandles. The advantage is that they would only check access once on creation and have some other optimizations that should make them faster than reflection in most cases.
Class<?> dynamicallyFoundClass = Class.forName("some.package.SomeClass");
Class<?> fixedClass = SomeClass.class;
String methodName = "changeDirectory";
MethodType type = MethodType.methodType(void.class, String.class);
handles.put("cd", lookUp.findStatic(dynamicallyFoundClass, methodName, type));
handles.get("cd").invoke(args);
But how complicated an approach you have to use would depend on what you know at compile time and what has to be found at runtime.

how to create an object of a class in a different package in another class [duplicate]

This question already has an answer here:
Import custom Java class
(1 answer)
Closed 9 years ago.
I am a beginner at java, I used to code in C++ and there when using classes I used to define them in separate files and then include those classes in my main file.
I'm trying to learn threads for socket programming so I can open multiple server ports as threads and accept multiple clients. I know that in Java the file name should be the same as the class name (correct me if i am wrong). This is what I am trying to do:
main.java
include derived.java;
class main1
{
main1()
{
System.out.println("Constructor of main1 class.");
}
void main1_method()
{
System.out.println("method of main 1 class");
}
public static void main(String[] args)
{
main1 my = new main1();
Derived derivedThread = new Derived();
derivedThread.start();
}
}
derived.java
public class derived extends Thread
{
public void run()
{
System.out.println("starting a new thread");
}
}
How can I create a derived class object in main and include it in my main1.java file?
I think I do not fully understand how classes work in Java and what classpath has to be used with it. I have a deadline for my networking project and I am very behind so please help me!
Delete your files and try this, this is how it should look in Java:
Derived class: Derived.java
public class Derived extends Thread {
public void run() {
System.out.println("starting a new thread");
}
}
Main1 class: Main1.java
public class Main1 {
public Main1() {
System.out.println("Constructor of main1 class.");
}
void main1_method() {
System.out.println("method of main 1 class");
}
public static void main(String[] args) {
Main1 my = new Main1();
Derived derivedThread = new Derived();
derivedThread.start();
}
}
Note:
1) Class names are always capitalized, and you are right, the filename must be the same. In addition, the constructor and any calls to the constructor must be capitalized.
2) If you put classes in the same package, you don't need to import them. If you have multiple packages, you would import like so: import packageName.className;. No need for .java at the end, strictly the class name. You can also have nested packages, so you might see things like: import java.util.ArrayList;. This would be using ArrayList class, found in the util package, which is in the java package (built in). You shouldn't have to worry much about making nested packages on smaller projects, but that's the concept.
3) Notice I added the public modifier to Main1 and it's constructor. It is good practice to give a modifier to class names and methods, as well as class variables. See this SO Question for information about modifiers. For a beginner, you should mostly only be concerned with public and private.
I hope that helps, and good luck with your Java studies.
No need to use this include derived.java; .Use import if the derived class exist in different package.The class Derived is different while calling and declaring.
class main1 // Class name must start with Uppercase
{
public static void main(String[] args)
{
main1 my = new main1(); // Can be remove
Derived derivedThread = new Derived();
derivedThread.start();
}
}
public class derived extends Thread // Change derived to Derived
--------------------^
{
public void run()
{
System.out.println("starting a new thread");
}
}
I have remove constructor and one method which is not used.

Java Packages - Import vs Explicit Inclusion

I thought I reasonably understood the use of packages but am experiencing an ostensibly trivial issue when attempting to use a method from an imported package.
I have three files in the following directory structure:
Tester.java
approach1\Approach.java
approach2\Approach.java
Their code is as follows:
Tester.java
import approach1.Approach;
public class Tester {
public static void main(String[] args)
{
approach1.Approach.sharedMethod("TEXT");
sharedMethod("TEXT");
}
}
approach1\Approach.java
package approach1;
public class Approach {
public static void sharedMethod(String approachText)
{
System.out.println("Approach Text: " + approachText);
}
}
approach2\Approach.java
package approach2;
public class Approach {
public static void sharedMethod(String approachText) { }
}
As you can likely guess, I'm trying to elicit different responses from the different approaches based on what package/class is imported. The problem I encounter is within Tester.java. The first, explicit line works fine whereas the second, imported line (sharedMethod("TEXT")) throws an error of "The method sharedMethod(String) is undefined for the type Tester". I don't understand as I have imported one of the packages, so the method should be visible.
Any clarification would be appreicated as I'm a Java newb. Thanks!
You could import your static method shareMethod like this
import static approach1.Approach.sharedMethod;
the standard kind of imports that you have used only import the classes - so everything within a class must be referenced using the class name. just use:
Approach.sharedMethod()
and now the compiler will be able to know which method to use all depending on which Approach class you have imported at the top.
Just to clarify:
import approach1.Approach;
public class Tester {
public static void main(String[] args)
{
Approach.sharedMethod("TEXT");
}
}
is different from
import approach2.Approach;
public class Tester {
public static void main(String[] args)
{
Approach.sharedMethod("TEXT");
}
}
You should only specify the class name and leave it to the package import statement at the top to determine which package to find the class/methods from.
You only need to explicitly mention the package in the main program body if there is a conflict in names or if you have not imported anything.

Categories

Resources