I am just testing dynamic class load and am doing this:
package P1;
public class Class1
{
public static void main(String[] args)
{
Bird myBird = null;
String myClassName = "P2.Bird";
Class x = Class.forName(myClassName);
myBird = (Bird)x.newInstance();
}
}
Bird is a class from package P2, and Class1 is from P1. What should I add in the code to make this work, as the String myClassName... line shows an error (class not found). I tried the same code after moving Bird in package P1, even then it doesn't work.
Related question: Why would someone use dynamic class load, does it have any advantages? It's much simpler(at least for me at first glance) to just use the "new" operator for static class loading, and in that case I know how to refer the class from a different package. Many thanks!
For the answer to your first question try mentioning full Package name. I have tried it and it works
Your Bird class provides a default public constructor with no arguments?
Dynamic class loading can be useful for example to specify the class you want to use in a configuration file (you will come across that if you ever use log4j, or other libraries that allow the use of your own implementation to one of their interfaces). In that case, the library does not know about which class you will use, and you don't have to write code to initialise the library (which would be the alternative to dynamic class loading, but which is less convenient)
Related
I would like to be able to add a file with the java structure and extension into my program to an arraylist via outside the actual program directory/jar.
Ex,
Test.java, located at C:\Users\user\Desktop\Test.java (Outside the jar)
public class Test extends Object {
public Test() {}
public void someMethod() {}
}
MyProgram.java
import java.util.ArrayList;
public class MyProgram extends Object {
public MyProgram() {}
public void readIn() {
ArrayList<Object> list = new ArrayList<Object>();
list.add(Test.java);
}
}
Obviously a lot more will have to be done but hopefully you understand the point.
Read In Test.java -> Convert it somehow so it's added to the arraylist due to it's extension. So if the extension was Family instead of Object, the arraylist would be ArrayList instead and Test extends Family.
Edit
As stated by a comment, this is an approach to a plugin mechanism.
The answer to this question stems from Seelenvirtuose's suggestion along with crick_007. To access classes outside the class path, simply create a ClassLoader and load the class in.
You must also use an interface to interact between the two classes, also knowing what methods are provided. Lastly, packaging must also be the same or else you'll get errors such as
PACKAGENAME.CLASS cannot be cast to PACKAGENAME.CLASS even if the class has the same name as in your program (A test I tried)
I have two questions:
1) Is there a way to extend of class A from external file ? how?
2) I am building one class of my custom methods ( to use globally, in all my projects). Here is phseudo-code:
package MyFunctions;
import Twitter.profile;
public class MyFuncs{
public String externalProfile1() { return Twitter.profile.TwitterUrl(); }
}
I want Is there a way to include that file in all my projects, and avoid IDE errors, as I should be able to use any when one of the above functions in my projects... The problem is that the Twitter.Profile classes are not included in all my projects, and whenever happens so - it see error in IDE("cannot find symbol method")...
how to solve the problem?
Question 2:
Just make sure all of your functions in your library are written statically:
public class MyFuncs{
public static String externalProfile1(String link) { return TwittUrl() + "/profile"; }
public static String externalProfile2(String link) { return YahooUrl() + "/profile"; }
}
And then import that class in your project files that you'll be using your library in. Then you can easily call the functions in your library. Alternatively, you can avoid importing the library in every other file and instead call the functions in a static way:
MyFuncs.externalProfile1("link");
As for TwittUrl(), if it doesn't require to be in a separate Class, then refactor it and put it in MyFuncs class; otherwise you can make TwittUrl() and YahooUrl() methods static in their own class.
I love the Intellij IDEA but i have been stacked on one little problem with Java imports.
So for example there is a package with name "example" and two different classes in it: A.java and B.java.
And i wanna get access to class "A" from class "B" without imports. Like this:
class A:
package example;
public class A{ ... some stuff here ...}
class B:
package example;
public class B{
public static void main(String[] args){
A myVar = new A();
}
}
This code may not work, but it's doesn't matter. Trouble just with IDE and with its mechanism of importing classes.
So, problem is that i can't see A class from B. Idea says 'Cant resolve symbol' but i actually know that class A exists in package. Next strange is that complier works fine and there are no exceptions. Just IDEA can't see the class in the same package.
Does anybody has any ideas?
If they are in the same package, you can access A in class B without import:
package example;
public class B{
public static void main(String[] args){
A myA = new A();
}
}
Maybe this will help you, or somebody else using IntelliJ that is getting a "Cannot resolve symbol" error but can still compile their code.
Lets say you have the two files that buymypies wrote up, the standard Java convention is that the two files would exist in an Example directory in your source code area, like /myprojectpath/src/Example. But it is technically not a requirement to reflect the package structure in the source directory structure, just a best practice sort of thing.
So, if you don't mimic the package structure, and the two files are just in /myprojectpath/src, IntelliJ will give you the "Cannot resolve symbol" error because it expects the source code structure to reflect the package structure, but it will compile okay.
I'm not sure if this is your problem, but I do use IntelliJ and have seen this, so it's something to look at.
I have the same problem as this: 2 classes in the same package, yet when one tries to call the other, Intellij underlines it in red and says Cannot resolve symbol 'Classname', e.g. Cannot resolve symbol 'LocalPreferencesStore'.
It then wants to add the fully qualified name in situ - so it clearly knows the path - so why can't it just access the class?
The module still compiles and runs, so it's just the IDE behaving oddly - and all that red is very distracting, since it isn't actually an error, it's just IDEA throwing a weird wobbly.
This is also recent. Two weeks ago I wasn't having this problem at all, and now suddenly it's started up. Of course, it could go away again on its own soon, but it's really annoying.
Same issue and I just fixed it.
I don't know your folder structure.
However, if your package example was added manually.That's the problem.
The package should be the same as your folder structure,which means if you want your class file to be stored in package example,you must store you java file in the src's subfolder named example.
You need to learn the basics about Java i think.
Here is a basic example of what i think you are trying:
package Example;
public class A
{
String myVar;
public String getMyVar()
{
return myVar;
}
public void setMyVar(String myVar)
{
this.myVar = myVar;
}
}
You need to create an instance of A.
package Example;
public class B
{
/**
* #param args
*/
public static void main(String[] args)
{
// TODO Auto-generated method stub
A myA = new A();
myA.setMyVar("Hello World!");
System.out.println(myA.getMyVar);
}
}
Look up java 'getters' and 'setters'.
In Java, you can define multiple top level classes in a single file, providing that at most one of these is public (see JLS §7.6). See below for example.
Is there a tidy name for this technique (analogous to inner, nested, anonymous)?
The JLS says the system may enforce the restriction that these secondary classes can't be referred to by code in other compilation units of the package, e.g., they can't be treated as package-private. Is that really something that changes between Java implementations?
e.g., PublicClass.java:
package com.example.multiple;
public class PublicClass {
PrivateImpl impl = new PrivateImpl();
}
class PrivateImpl {
int implementationData;
}
Javac doesn't actively prohibit this, but it does have a limitation that pretty much means that you'd never want to refer to a top-level class from another file unless it has the same name as the file it's in.
Suppose you have two files, Foo.java and Bar.java.
Foo.java contains:
public class Foo
Bar.java contains:
public class Bar
class Baz
Let's also say that all of the classes are in the same package (and the files are in the same directory).
What happens if Foo refers to Baz but not Bar and we try to compile Foo.java? The compilation fails with an error like this:
Foo.java:2: cannot find symbol
symbol : class Baz
location: class Foo
private Baz baz;
^
1 error
This makes sense if you think about it. If Foo refers to Baz, but there is no Baz.java (or Baz.class), how can javac know what source file to look in?
If you instead tell javac to compile Foo.java and Bar.java at the same time, or if you had previously compiled Bar.java (leaving the Baz.class where javac can find it), or even if Foo happens to refer to Bar in addition to Baz, then this error goes away. This makes your build process feel very unreliable and flaky, however.
Because the actual limitation, which is more like "don't refer to a top-level class from another file unless it either has the same name as the file it's in or you're also referring to another class that's named the same thing as that file that's also in that file" is kind of hard to follow, people usually go with the much more straightforward (though stricter) convention of just putting one top-level class in each file. This is also better if you ever change your mind about whether a class should be public or not.
Newer versions of javac can also produce a warning in this situation with -Xlint:all:
auxiliary class Baz in ./Bar.java should not be accessed from outside its own source file
Sometimes there really is a good reason why everybody does something in a particular way.
My suggested name for this technique (including multiple top-level classes in a single source file) would be "mess". Seriously, I don't think it's a good idea - I'd use a nested type in this situation instead. Then it's still easy to predict which source file it's in. I don't believe there's an official term for this approach though.
As for whether this actually changes between implementations - I highly doubt it, but if you avoid doing it in the first place, you'll never need to care :)
I believe you simply call PrivateImpl what it is: a non-public top-level class. You can also declare non-public top-level interfaces as well.
e.g., elsewhere on SO: Non-public top-level class vs static nested class
As for changes in behavior between versions, there was this discussion about something that "worked perfectly" in 1.2.2. but stopped working in 1.4 in sun's forum: Java Compiler - unable to declare a non public top level classes in a file.
You can have as many classes as you wish like this
public class Fun {
Fun() {
System.out.println("Fun constructor");
}
void fun() {
System.out.println("Fun mathod");
}
public static void main(String[] args) {
Fun fu = new Fun();
fu.fun();
Fen fe = new Fen();
fe.fen();
Fin fi = new Fin();
fi.fin();
Fon fo = new Fon();
fo.fon();
Fan fa = new Fan();
fa.fan();
fa.run();
}
}
class Fen {
Fen() {
System.out.println("fen construuctor");
}
void fen() {
System.out.println("Fen method");
}
}
class Fin {
void fin() {
System.out.println("Fin method");
}
}
class Fon {
void fon() {
System.out.println("Fon method");
}
}
class Fan {
void fan() {
System.out.println("Fan method");
}
public void run() {
System.out.println("run");
}
}
Just FYI, if you are using Java 11+, there is an exception to this rule: if you run your java file directly (without compilation). In this mode, there is no restriction on a single public class per file. However, the class with the main method must be the first one in the file.
1.Is there a tidy name for this technique (analogous to inner, nested, anonymous)?
Multi-class single-file demo.
2.The JLS says the system may enforce the restriction that these secondary classes can't be referred to by code in other compilation units of the package, e.g., they can't be treated as package-private. Is that really something that changes between Java implementations?
I'm not aware of any which don't have that restriction - all the file based compilers won't allow you to refer to source code classes in files which are not named the same as the class name. ( if you compile a multi-class file, and put the classes on the class path, then any compiler will find them )
Yes you can, with public static members on an outer public class, like so:
public class Foo {
public static class FooChild extends Z {
String foo;
}
public static class ZeeChild extends Z {
}
}
and another file that references the above:
public class Bar {
public static void main(String[] args){
Foo.FooChild f = new Foo.FooChild();
System.out.println(f);
}
}
put them in the same folder. Compile with:
javac folder/*.java
and run with:
java -cp folder Bar
According to Effective Java 2nd edition (Item 13):
"If a package-private top-level class (or interface) is used by only
one class, consider making the top-level class a private nested class
of the sole class that uses it (Item 22). This reduces its
accessibility from all the classes in its package to the one class
that uses it. But it is far more important to reduce the accessibility
of a gratuitously public class than a package-private top-level class:
... "
The nested class may be static or non-static based on whether the member class needs access to the enclosing instance (Item 22).
No. You can't. But it is very possible in Scala:
class Foo {val bar = "a"}
class Bar {val foo = "b"}
I have found one error in my Java program:
The public type abc class must be defined in its own class
How can I resolve this error? I am using Eclipse. I am new to Java programming.
Each source file must contain only one public class. A class named ClassName should be in a file named ClassName.java, and only that class should be defined there.
Exceptions to this are anonymous and inner classes, but understanding you are a beginner to Java, that is an advanced topic. For now, keep one class per file.
Answering your addition: it is OK to inherit classes and that's totally fine. This does not matter, each class should still have its own file.
Public top-level classes (i.e. public classes which aren't nested within other classes) have to be defined in a file which matches the classname. So the code for class "Foo" must live in "Foo.java".
From the 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 rule, which doesn't have to be followed by compilers, is pretty much universally adhered to.
Ok, maybe an example will help.
In file MySuperClass.java:
public class MySuperClass {
// whatever goes here
}
public class MySubClass1 extends MySuperClass {
// compile error: public class MySubClass1 should be in MySubClass1.java
}
class MySubClass2 extends MySuperClass {
// no problem (non-public class does not have to be in a file of the same name)
}
In file MySubClass3.java:
public class MySubClass3 extends MySuperClass {
// no problem (public class in file of the same name)
}
Does that make things clearer?
A public class with the name of "abc" must be in a file called abc.java
You can create a new class an a existing file if it's private, but you should not do this.
Create one file per class.
Eclipse does that for you, if you create a new class.
For programming Java, you have to understand the construct of classes, packages and files. Even if Eclipse helps you, you have to know it for yourself. So start reading Java books or tutorials!