Okay, not sure if this would work.. but would it be possible, to use my own Java file that has certain required methods in it, to be imported into my Java class just like any other import? Or does it have a special way?
If your Java file contains a proper Java class enclosing the methods mentioned above, and it is visible to the compiler (i.e. either its source file is on the compiler source path or its class file is on the compiler classpath), you can just import it like any other classes.
Have you tried it? Do you have any specific problem?
If that method is static and visible in your scope, you can use import static. It will make the imported static method look like it is in your class. For example, if your code parse a lot of integers, you can use
import static Integer.parseInt;
And then the parseInt method will be visible and invokable directly:
int parsed = parseInt("123");
That is only required if your other class is in a different namespace. if they are in the same namespace (this includes the default empty namespace), and you 'tell' the compiler about both files, you don't need to use import statements.
If however class A is in namespace org.example.stuffA, and you want to use it in class B in org.example.stuffB, you'll need to use a import org.example.stuffA.A statement, or hard-link it in the document (new org.example.stuffA.A() for example).
In the namespaces example, you still need to make sure the compiler is able to find the required classes. In both cases you also need to make sure the methods you need are of the correct permission type, they would probably need to be public.
You Can use Static methods or by create Object of it & Use.
public class abc
{
public static MyMethod()
{
// ..
}
}
public class pqr
{
abc.MyMethod();
}
Another Way
public class abc
{
public void MyMethod()
{
// ..
}
}
public class pqr
{
abc Obj=new abc();
Obj.MyMethod();
}
Related
I have a simple code:
public class Hello
{
public static void main(String[] args)
{
System.out.println("Hello World");
}
}
I know that Object class is imported by default in every java program, but I wanted to ask whether PrintStream class is also imported by default if we are using print() or println() functions?
Because Object class belongs to java.lang package and PrintStream class belongs to java.io package, so if it is not imported by default, then how we are able to use the println() method of PrintStream class?
If it (PrintStream class) is not imported by default, then why the decompiler is importing it?
This is the output after decompiling it:
The types of intermediate expressions in your Java program do not need to be imported on the source code level. It's only when you assign the value of such an expression to a declared variable that you have to make its type explicit; at that moment you have to add the import (or use the qualified name).
In your case, System.out is such an intermediate expression; its type is indeed java.io.PrintStream, which is not imported by default as it is not in java.lang. If you would modify your class to
import java.io.PrintStream;
public class Hello {
public static void main(String[] args)
{
PrintStream myOut = System.out;
myOut.println("Hello World");
}
}
you need to add the import statement, or use the qualified name as in
public class Hello {
public static void main(String[] args)
{
java.io.PrintStream myOut = System.out;
myOut.println("Hello World");
}
}
On the bytecode level the story is different: since all dependencies need to be loaded for the JVM to be able to execute the code, all of them are listed in the .class file, including the types of intermediate expressions. Apparently the decompiler used in the screenshot of the OP isn't clever enough to realise that such imports are unnecessary on the source code level, and so it just creates import statements for all dependencies listed in the .class file.
I wanted to ask whether PrintStream class is also imported by default if we are using print() or println() functions
No, from the JLS:
A compilation unit automatically has access to all types declared in its package and also automatically imports all of the public types declared in the predefined package java.lang.
So you can use System because it belongs to java.lang.
so if it is not imported by default,then how we are able to use the println() method of PrintStream class?
Because System.out is accessible to your type, so you can use all visible method of System.out
why the decompiler is importing it
Looks like a bug in the decompiler you are using. This import is completely unnecessary here.
You can program without imports at all, just using the fully-qualified class names like this:
java.io.PrintStream out = System.out;
Imports are used just for convenience, so you can use simple class names in your code. It's possible that the same simple name appears in different packages (for example, java.awt.List and java.util.List) so to resolve this ambiguity you have to either use full class name or import the one you want (in case you want to use both of them, you will still have to use the full name for one of them). As you correctly mentioned, only classes from java.lang are imported always by default. Again, this is done for convenience, so you can use just System instead of java.lang.System (though java.lang.System.out.println() is also valid).
In your example as you don't directly mention the PrintStream in the source, no need to import it. Imports have nothing in common with class loading (which happens in runtime, not during the compilation).
I'm looking for a way to add some methods into exists class like this:
String s = "";
s.doSomething();
In objective C, I can use category to do this.
#interface NSString( Stuff)
-(void)doSomething();
#end
Is android has something like that? Or another hack?
Update: Actually, I got this problem: I use a class (not final) from jar file (so, I can't touch its source code). Then I want to add methods( or something like that) into this class without using inheritance. For example:
public class Provider{
// many methods and fields go here...
public String getName(){}
}
All I want to do is:
provider.print(); //that call getName() method;
I also tried proxy pattern, it worked, but I don't like that way (because it like a wrapper class, I must store an object with many fields and methods to use only one method):
public class ProxyProvider{
Provider provider;
public ProxyProvider(Provider provider){
this.provider = provider;
}
public void print(){
String name = provider.getName();
//do something
}
}
Is there any way to solve that?
You could create a utility class with static methods:
public final class ProviderUtils {
private ProviderUtils() {} // not instantiable, it is a utility class
public static void print(Provider provider) {
String name = provider.getName();
// print the name
}
}
In your code, you can then call it:
Provider p = new Provider(...);
ProviderUtils.print(p);
And if that class only has one print method, you can maybe call it ProviderPrinter instead of ProviderUtils.
In the end you don't have thousands of possibilities - you can:
extend the class and whatever method you need in the sub class => you said you don't want that
modify the source code of the class and recompile your own version of the jar
wrap the class in a wrapper that adds the methods you need (your ProxyProvider example)
put the methods you need in a static utility class (what I proposed above)
modify the class at runtime and add a method, but that's a complicated path because you need to play with classloaders.
It is not possible, however, there is a java like DSL available called Xtend that can be used as a compelling replacement for JAVA that might be work looking at which supports extension methods like this.
http://www.eclipse.org/xtend/
DISCLAIMER: I am in no way associated to this I am just an avid user of the core technology that was used to create xtend called xtext. I have considered using xtend on an Android project
In Java, a class can be extended using regular inheritence unless it final. String is final, because Strings are immutable, and therefore are intentionally protected against subclassing.
Also, adding behaviour by subclassing is considered bad practice in many cases - the coupling is simply too strong and sticks with you for instances of your objects you are ever going to create. The rule of thumb is "favour composition over inheritance".
Having said this, there are many approaches / patterns to solve your special problem. Decorator might be the pattern you are looking for.
Please update your question or post a new one with more information.
Try to extend the class in question and add your methods to it. if that can't be done (like it's been said, String is final) then just write a wrapper around it with the methods you want and the object you want to extend.
Like
public class MyString
{
private String internal;
//your methods
}
try to further elaborate your problem so i can give a better answer. like whats the real object in question and what you really wanna do, if you can disclose it that is.
I have file TestClass.java
package com.fido.android.sample.dsm.SoftPin.Core;
public class TestClass
{
public int mValue1;
public String mValue2;
}
Now in this file (TestClass.java) I want to declare one more class, but when I write for example:
public class SecondClass
{
// Class members goes here.
}
Compiler do not allow me to do that, if I remove public everything is Okay, but I can use SecondClass only in the TestClass.java, I can't write
SecondClass sc = new SecondClass();
out of TestClass.java class. Now I want to know if there is a way to do such thing, to have two classes in the same file and to use them from everywhere (not inner classes).
Question is: Why would you want to declare a second public class within the same Java class file? It is a rule in Java that each public class must be declared in a single class file - except for nested classes like Graham Borland pointed out.
Short answer: You can't.
That's how Java works.
You can only declare a single public class per file, with the class name the same as the file name.
You can use inner-classing as Graham suggested, or better yet, move the second class in a new file.
If you have SecondClass inside TestClass (i.e. nested inside the class definition), with public visibility, then you can refer to TestClass.SecondClass everywhere.
No, you can't, if the compiler chooses to enforce this rule from the Java Language Specification, section 7.6:
When packages are stored in a file system (ยง7.2.1), the host system may choose to enforce the restriction that it is a compile-time error if a type is not found in a file under a name composed of the type name plus an extension (such as .java or .jav) if either of the following is true:
The type is referred to by code in other compilation units of the package in which the type is declared.
The type is declared public (and therefore is potentially accessible from code in other packages).
This restriction implies that there must be at most one such type per compilation unit.
So this is optional in that it's still "legal Java" to include more than one public top-level class in a single source file - but it's also valid for the compiler to reject it. In practice, I think every file-based Java compiler I've ever used enforces this rule.
Now you could try to find a different compiler if you really wanted, but there's a reason for this: Java programmers are used to finding the source code for a public top-level type (and usually any top-level type) in a source file with the same name.
To ask a return question provocatively: why do you want to make your source code hard to navigate?
You cannot.
What you can do is to have inner classes.
According to java conventions, A public class should be created in a separate file having same name as of class name.
So you cannot make two public classes in same file.
you can try either removing public from one class or making inner class.
Since public classes must have the same name as the source file , there can only one pulbic class inside a java file.
I'm a Java noob.
Here's what I'm trying to do:
//File 1
public class Class1
{
//....does some stuff
}
//File 2
public class Class2
{
//..also does some stuff including:
Class1 c = new Class1();
}
File 1 and File 2 are in the same directory.
To compile, I'm using the command:
javac Class2.java
This is giving me errors of the form:
Error: Cannot find symbol Class1
How do I solve this?
If the two files Class1.java and Class2.java are in the same directory, (and assuming you have declared the class you want to use as) you do not need to do any import at all in order to use one from the other; Java will find the other class automatically.
So in Class2.java you can simply do:
public class Class2 {
void someMethod() {
Class1 c = new Class1();
}
}
On base class,
package ABC;
public class PQR {
// Do stuff
}
import ABC.*;
class XYZ {
// Use the PQR class method
}
Assuming they are in the same folder, you shouldn't have to import, if they aren't then you need to specify the package like import java.util.Scanner;. In Java you don't suffix with an extension.
What are you using to write your code in?
not sure I understand the question - are you trying to use an inner class (one class definition inside another class definition) or are these classes separate and independent? imports are required to define the packages/ classes you would have an access to, the ones in the same package are available by default. So if these are in the same package, you don't really need any imports. Also, both these classes need to be visible to each other. When you say it doesn't work, what error do you get?
one way to use inner classes is e.g. outer.new Class1() (where outer is an object of the class that encapsulates Class1). If these are not inner classes, they need to be in separate .java files.
Btw, it is always recommended to provide an access modifier (public, private, protected) explicitly.
Full code listing with error messages would help me give a better answer...
For using multiple classes in one file take a look into this tutorial
If you are writing your classes in two different files and they are in the same package it doesn't require to import them in order to use it. But if you are compiling them manually (using command prompt) make sure you have compiled all the .java file. Otherwise you will get errors.
If you are writing them in different package make sure these classes are public in order to use them. And yes in this case you have to import the package containig the class that you want to use. Again make sure all the classes are compiled if you are using command promt.
My suggestion is to use a good IDE (there are many :)) for doing your code because they assist you much more than we do :)
Okay, so a java source file must have at least one public class and the file should be called "class-name.java". Fair enough.
Hence, if I have a class, then the following would compile:
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World!"); // Display the string.
}
}
But what bugs me is that if I remove the 'public' access modifier from the above code, the code still compiles. I just don't get it. Removing it, the code looks like:
class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World!"); // Display the string.
}
}
In the above code, since I removed the public access modifier, my class has default or package access, i.e. it can't be accessed from the outside world, only from within the package.
So my question is, how does the above code compile ? The file HelloWorld.java in this case does not have a public HelloWorld class (only a package-private HelloWorld.class) and thus to my understanding should not compile.
a java source file must have at least one public class and the file should be called class-name.java
Incorrect, a top level class does not have to be declared public. The JLS states;
If a top level class or interface type is not declared public, then it may be accessed only from within the package in which it is declared.
See http://java.sun.com/docs/books/jls/second_edition/html/names.doc.html#104285 section 6.6.1.
You can place non-public class in a file, and it's not a bug but feature.
Your problem is on level of packaging, not compile. Because you can compile this file with non-public class, but you can't call it from outside, so it's not working as application base class
Like this:
// [+] single file: SomeWrapper.java
public class SomeWrapper {
ArrayList<_PrivateDataType> pdt;
}
// [-] single file: SomeWrapper.java
// [+] single file: _PrivateDataType.java
class _PrivateDataType {
// members, functions, whatever goes here
}
// [-] single file: _PrivateDataType.java
A main method is just like any other method. The only difference is that it may be invoked from the command line with the java command. Even if the main method is not visible from the command line, the class can still be used like any other Java class, and your main method may be invoked by another class in the same package. Therefore i makes sense that it compiles.
In Java main function are not special in any sense. There just exists a terminal command that is able to invoke static methods called main...
There are valid usages for a non public classes. So the compiler does not give error when you try to compile the file.
That's nothing to wonder about. I suppose this behavior is similar to the one of some C/C++-compiler.
Code like "void main() { /.../ }" will be compiled correctly by those compilers, although it is not standards-compliant code. Simply said, the compiler exchanges the "void" with "int".
I think a similar behavior is implemented by the java compiler.
When you do not specify the access modifier of the class (or its field or method), it is assigned "default" access. This means it is only accessible from within the same package (in this case, the default package).
The website Javabeginner.com has an article on the subject - you should become familiar with access modifiers in Java, either from this site, or others.