Reputation: 10647
I have two Java class files: primegen and primecheck sitting in the same directory. primegen calls a public static function from primecheck. primecheck compiles fine.
However, I receive the following compilation error in primegen:
primegen.java:31: cannot find symbol
symbol : variable primecheck
location: class primegen
} while (!primecheck.prime(primeCandidate));
^
Shouldn't Java be checking other (compiled) classes within the same directory? Does Java have a problem with primecheck being in lower-case letters (e.g. Is it treating primecheck as a variable instead of a class?)?
Update with Complete Code
Code for primegen:
import java.math.BigInteger;
import java.util.Random;
public class primegen
{
public static void main(String args[])
{
try
{
int numBits = Integer.parseInt(args[0].trim());
System.out.println(generatePrime(numBits));
}
catch (Exception e)
{
System.out.println("You must enter a positive integer number of bits.");
}
}
private static BigInteger generatePrime(int numBits) throws Exception
{
if (numBits < 1)
throw new Exception("You must enter a positive integer number of bits.");
BigInteger primeCandidate;
Random rand = new Random();
do
{
primeCandidate = new BigInteger(numBits, rand);
} while (!primecheck.prime(primeCandidate));
return primeCandidate;
}
}
Code for primecheck:
import java.math.BigInteger;
import java.util.Random;
public class primecheck
{
public static void main(String args[])
{
try
{
BigInteger primeCandidate = new BigInteger(args[0].trim());
if (prime(primeCandidate))
System.out.println("True");
else
System.out.println("False");
}
catch (Exception e)
{
System.out.println("You must enter a positive integer.");
}
}
public static boolean prime(BigInteger n) throws Exception
{
if (n.compareTo(BigInteger.ZERO) == -1)
throw new Exception("You must enter a positive integer.");
else if (n.equals(BigInteger.ZERO) || n.equals(BigInteger.ONE))
return false;
int maxIterations = 1000;
BigInteger a;
for (int i = 0; i < maxIterations; i++)
{
a = randomBase(n);
a = a.modPow(n.subtract(BigInteger.ONE), n);
if (!a.equals(BigInteger.ONE))
return false;
}
return true;
}
private static BigInteger randomBase(BigInteger n)
{
Random rand = new Random();
BigInteger a;
do
{
a = new BigInteger(n.bitLength(), rand);
} while ( !(BigInteger.ONE.compareTo(a) <= 0 && a.compareTo(n) < 0) );
return a;
}
}
Upvotes: 0
Views: 565
Reputation: 21995
Java does not care about names being all lowercase or uppercase. These are just naming conventions (Java is case sensitive, but will not enforce any particular naming convention).
Edit: (after a few iterations :)
The code you posted compiles fine. The problem is obviously somewhere else (javac command line arguments, classpath...)
Upvotes: 2
Reputation: 76709
There appears to be a symbol conflict in your primegen
class.
Declaring another variable primecheck
within the same scope results in confusing the compiler on how it should be treating the reference - is the code referencing the class or the object? It ends up treating it as an object reference, and since the object's class does not have the method prime()
defined in it, it throws up the error. Of course, the example also vindicates why naming conventions are a good idea.
Consider the following snippets of code, and the resulting error when compiling primegen
.
Class primegen
import java.math.BigInteger;
import java.util.Random;
public class primegen
{
public static void main(String args[]){}
private static BigInteger generatePrime(int numBits) throws Exception
{
if (numBits < 1)
throw new Exception("You must enter a positive integer number of bits.");
BigInteger primeCandidate;
Random rand = new Random();
String primecheck = "";
do
{
primeCandidate = new BigInteger(numBits, rand);
} while (!primecheck.prime(primeCandidate));
return primeCandidate;
}
}
Class primecheck
import java.math.BigInteger;
public class primecheck
{
public static void main(String args[]){}
private static BigInteger randomBase(BigInteger n){return null;}
public static boolean prime(BigInteger n) throws Exception
{
if (n.compareTo(BigInteger.ZERO) == -1)
throw new Exception("You must enter a positive integer.");
else if (n.equals(BigInteger.ZERO) || n.equals(BigInteger.ONE))
return false;
int maxIterations = 1000;
BigInteger a;
for (int i = 0; i < maxIterations; i++)
{
a = randomBase(n);
a = a.modPow(n.subtract(BigInteger.ONE), n);
if (!a.equals(BigInteger.ONE))
return false;
}
return true;
}
}
The resulting error is:
primegen.java:18: cannot find symbol
symbol : method prime(java.math.BigInteger)
location: class java.lang.String
} while (!primecheck.prime(primeCandidate));
^
1 error
Upvotes: 0
Reputation: 76709
Since this is a compilation error, rather than a runtime one, it is important to understand that the compiler cannot find the primecheck
class when compiling primegen
. The current directory (by inference, the current package) is included by default, by the javac compiler in the user classpath, whenever any symbols have to be resolved during compilation. However, if this is overridden by the CLASSPATH environment variable, then symbol resolution will fail.
There is also a likelihood (I haven't verified this) that the '.' symbol in the classpath environment variable is not expanded into the current working directory, and hence it would be better to explicitly specify the location of the .class files.
Therefore, it is important to specify the location of the primecheck class when compiling primegen, either by the -classpath
option (to indicate where the .class files can be found) or the -sourcepath
option (to indicate where the compiler can find the source code of the class).
Reference:
Upvotes: 0
Reputation: 1074228
Check your classpath — does it have "." in it? If not, no, Java will not look in the current directory for classes.
No, Java doesn't care about the class names being in all lower case (provided they're consistently lower case, both where used and where defined), but the convention is for classes to have a capital first character (and usually to be camelCase), e.g. PrimeGen
and PrimeCheck
vs. primegen
and primecheck
. It doesn't relate to your problem, but it will tend to startle and confuse people looking at the code (like people on SO). :-)
Update Are these classes in a package? If so, you need to be sure that they're in the right place relative to the class path as relates to the package. But typically that would have shown up on your import
statement, as opposed to your use of primecheck
...
Upvotes: 2
Reputation: 81074
Java is case sensitive. Perhaps your class is defined as PrimeCheck
or something similar?
Upvotes: 2