Object Oriented programming
sorry for the lack of clarity.
our teacher gave us this example its a singleton and factory pattern program combined however when I run it in java it keeps telling me that the class fromExperian doesn't exist. I've retyped it word for word in eclipse and double checked for anything different it's one program all in the same file.
the issue:
I get an error message saying that the class doesn't exist even when it does.
okay so this is the pdf document each screen shot is a page. So if I type into the scanner in the main I'll get fromExperian class doesn't exist, or fromTransUnion class doesn't exist etc.
It looks like it can't find the classes even though they are in the same file?
Your code works for me. But only as long as it exists in the default package!
You have to use Class.forName(...) with the canonical class name. So as long as you are not in the default package your error occurs.
penCheck = (pen)Class.forName(s).newInstance();
leads to your error if your class does not lie in the default package.
penCheck = (pen)Class.forName(fromExperian.class.getCanonicalName()).newInstance();
instead will always work.
And yes it also works when fromExperian is abstract.
When you set the company to Experian, you then try to instantiate the fromExperian class. That can't happen, as fromExperian is abstract.
You'll have to make your fromExperian class concrete by removing the abstract keyword, or create at least a concrete class named (which name starts with "from") that extends fromExperian and set the company name accordingly.
I am not sure where your files are. Make sure all your .java files are in the proper spots. I don't know the details but when you get this kind of error I believe it's because the JVM can't find the .class file that the compiler was supposed to have made. When you compile it check your classpath and make sure everything is in the right packages and what not. Your single_factory_pattern.class or fromExperian.class is the culprit.
Related
I have my own System class with a Test class in the same package which test methods declared in the System class. I also have created a System constructor which takes 3 parameters. When I created a constructor to test the methods in my IDE the program was working fine (I had use java.util.System where I need to use the System. methods) but IDE knew I was referring to my own class when I created the constructor. However, when I trying running my test class from command line it won't even compile:
error: constructor System in class System cannot be applied to given types;
System sys = new System("String1", "String2", 20);
^
required: no arguments
found: String,String,int
reason: actual and formal argument lists differ in length
My guess is that instead of my constructor, the java.util.System constructor (with no parameters) is being invoked which causes the whole program to crash. Does anyone know how to fix it and why is it only happening in command line and not in IDE?
You mention java.util.System, but that's not where the platform's System lives; it lives in java.lang.
This is a problem. Java code acts as if import java.lang.*; is at the top of every file, even if you don't write it. The java language spec says so. So now you get into a fun dilemma:
Given a class named System in the same package, and you star-imported another package that also has a System class in it, which one is chosen if you use an unqualified type reference "System" someplace in the code?
The answer is presumably that whilst the spec is clear on this, few to no java coders care about the answer. They'd rather just.. not get into this bizarro situation. Thus, don't use star imports lightly, and don't name any classes the same as classes in the java.lang package.
If you must know, the order is as follows:
To resolve the type name System into which actual type it is referring to:
Check if there is a named (non-star) import for it: import java.lang.System;
Check if there is a class named System in this source file.
Check if there is a class named System in this package.
Check if there is a class named System in any star-imported package (and therefore, in java.lang as that is always star-imported.
Thus, given that it sounds like your System class is in the same package, that one 'wins'. However, if during a compilation run your non-test source files (your System.java file) is not on the classpath or sourcepath, then instead of the compiler straight up telling you this, instead you get the error you witness.
So, you have 2 problems:
you are not compiling the test classes on the command line correctly. Use a build system.
Don't name classes the same as classes in the lang package; whilst you can make code that works, and the ordering is well defined, it's confusing (hey, it confused you - that's anecdotal evidence right there!) and not idiomatic java. Other folks will have a very hard time reading your code, and you're likely to run into bugs in IDEs and such, because when you're doing weird unique things, odds go way up you run into scenarios nobody thought of and nobody ran into before.
I'm having a strange problem that I can't figure out that popped up when trying to pluginize my program. An additional problem is that I'm not able to create a simple test case, because every time I try it works. There must be some complication I'm missing. But I'll try to describe the situation as clearly as possible, in case it sounds familiar to anyone.
I have a base class called Seed which is part of the main application and loaded by the system classloader. I have a plugin which contains a class Road which is a subclass of Seed. It is loaded at runtime from a separate jar file. The class Road references the field Seed.garden, which is defined as:
protected final Garden garden;
Note that I don't get compilation errors. I also don't get runtime errors when the plugin jar is included on the system classpath. Only when my main application loads the plugin using a new classloader (that has the system classloader as its parent) do I get the error. The error is:
java.lang.IllegalAccessError: tried to access field package.Seed.garden from class package.Road$4
It must have something to do with the fact that the subclass has been loaded by a different class loader than the superclass, but I can't find any official reason why that shouldn't work. Also, like I said, when I try to reproduce the problem with a simple test case (that includes the separate jars, loading the subclass with a different classloader, etc.), I don't get the error.
It also doesn't seem likely that I'm violating the access rules since it works when the classes are loaded by the same classloader, and I don't get compilation errors.
I'm out of ideas! Does anyone recognise this problem, or have some pointers for me for directions in which to look? Help!
OK, so with the help of axtavt and other respondents I figured out what the problem is. The other answers helped, but they didn't get it exactly right, which is why I'm answering my own question. The problem turned out to be the concept of "runtime packages", defined in the Java Virtual Machine specification as follows:
5.3 Creation and Loading
...
At run time, a class or interface is determined not by its name alone, but by a pair: its fully qualified name and its defining class loader. Each such class or interface belongs to a single runtime package. The runtime package of a class or interface is determined by the package name and defining class loader of the class or interface.
...
5.4.4 Access Control
...
A field or method R is accessible to a class or interface D if and only if any of the following conditions is true: ...
R is protected and is declared in a class C, and D is either a subclass of C or C itself.
R is either protected or package private (that is, neither public nor protected nor private), and is declared by a class in the same runtime package as D.
The first clause explains why Road is allowed to access Seed.garden, since Road is a subclass of Seed, and the second clause explains why Road$4 is not allowed to access it, despite being in the same package as Road, since it is not in the same runtime package, having been loaded by a different class loader. The restriction is not actually a Java language restriction, it is a Java VM restriction.
So the conclusion for my situation is that the exception occurs due to a legitimate restriction of the Java VM, and I'm going to have to work around it, probably by making the fields public, which is not a problem in this case since they are final, and not secret, or perhaps by exporting Seed.garden to Road$4 via Road, which does have access.
Thank you everyone for your suggestions and answers!
Sounds like you have a class identity crisis, having two different class loaders loading the same class in the class hierarchy or similar. Read up some on the java class loaders. Here is a good one for introduction, for "class identity crisis" see figure 2: http://www.ibm.com/developerworks/java/library/j-dyn0429/
I should add that Road$4 is an anonymous inner class of Road...
Someone else thought this was a bug as well back in 1998:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4116802
An inner class has no greater access to members of another class than
a top-level class, except for those members that are declared within
an enclosing, enclosed, or sibling class. It is a common misconception
that an inner class has unrestricted access to inherited members of
its enclosing classes. This is not true.
I would probably research that fact a bit more though because this was reported originally against Java 1.2, but I seem to remember from my reading that this is true today as well.
EDIT:
I confirmed this to be true:
http://docs.oracle.com/javase/tutorial/java/javaOO/summarynested.html
The scope for an anonymous inner class is only the point where it is defined. So it will not have access to inherited members, even if the outer class does.
This is permission error, so it depends on the framework you use to run your runtime.
Just to clarify this is indeed this, make the parent member public, and then try to run. In case everything is ok, then restore your code, and according to the runtime you use we need to configure the correct security access.
As the title already says, I would like to know if it is somehow possible to give a class a different filename in Java with Eclipse ?
Edit: I only want to know if its possible with Eclipse. If you don't know the answer, please resist the urge to respond with condescending answers.
Edit2: It's hilarious what kind of responses I get here. All I wanted to know is if it is possible to have a class with a different filename (and I meant the public class) and nothing else. I thought this is the kind of forum to ask these questions, but the second response I got was already an insult. Is this some kind of taboo question or what is going on ?
Your filename should always match your class name, end of story. Although the JLS doesn't specifically state that it HAS to be done, they leave it up to the implementation of the compiler to make that decision. I'm pretty sure most (if not all) will not allow you to differ from that standard.
The JLS states:
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. This restriction makes it easy for a compiler for the Java programming language or an implementation of the Java virtual machine to find a named class within a package; for example, the source code for a public type wet.sprocket.Toad would be found in a file Toad.java in the directory wet/sprocket, and the corresponding object code would be found in the file Toad.class in the same directory.
So while you may be able to rename the file itself in eclipse, or your filesystem - you will more than likely hit a compile error.
I don't know why you would like to do that but it is possible if you compile files from command line with help of symbolic links.
Let's say you have class YourClass saved in a file OtherName.java. If you create a symbolic link to that file like this:
UNIX system: (for sure doesn't work on Solaris - other system aren't verified)
ln -s OtherName.java YourClass.java
javac YourClass.java
WINDOWS system: (works on Windows Vista/2008+)
mklink YourClass.java OtherName.java
javac YourClass.java
the compiler finds the type and compilation works...
This solution is not verified on Unix systems, but works for sure on Windows Vista/2008+..
What does Eclipse have with the naming conventions or rules of Java Programming Language?
Eclipse is just an IDE, and if you are working with Java you have to obey its rules.
Lets's say you have X.java file. This means that you can have only one public / abstract / final class named X in this file. There is no limitation on the number of classes and their names and also their nesting relations with each other as far as no more than one class holds the filename as its class name. If a class takes the filename, then it should have one or more of these modifiers: public, static, final. That's the story.
No, the Java a public class and the file must have the same name.
If you try to give the class another name, the compiler will fail with
class YourClass is public, should be declared in a file named YourClass.java
But you can declare additional private classes in a file which contains a public class.
below are the situations where you can have different class name.
1.class is not public class and exists in a java file where atleast one public class is defined
class notpublic{
}
public class PublicClass {
}
2.Class is a InnerClass .
public class PublicClass {
class InnerClass{
}
}
The error I get is exactly the error specified in:
http://java.syntaxerrors.info/index.php?title=Own_file
(class must be defined in its own file.)
but they don't give a solution there how to solve it, other than just having a file per public class.
Thank you, eclipse, for making me do this, but this is not mandatory in Java. Is there a way to get rid of this error?
Yes, it is mandatory in Java. Each public class has to be in a separate file named exactly the same way as the class.
See this question about it. The Java language specification writes that this is not 100% mandatory for compilers, but they usually do that. And since it is a good thing, and is noted in the spec, all compilers do it.
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 you want to have multiple classes in the same file, that's a different story. You can do it in two ways:
declare them as package-private classes with class Foo after the body of the main class. You can have any number of non-public classes in the same file
declare them as static inner classes: public static class InnerFoo inside the main class body. That way they will be visible to other classes by FooClass.InnerFoo
I have class in one package. and I am creating an instance of this class in another class which is in different package. When i want to use any methods on this object, i can use ctrl+space for code assist which shows all reachable methods which i can use. But in this case it is not showing any, even public setters and getters. So wanted to know am I missing something.
Thanks
You may need to add the package to your build path. Look here: http://www.informit.com/articles/article.aspx?p=367962