In the Previous part on Core Java Interview Questions, I had posted 50 questions. Since the post was getting too big, I left out some questions which are posted in this one.
Apart from the questions below, there are a few articles that I have put up (as part of the SCJP Certification series) that cover these topics, which you might find useful. You can use them to revise/review your understanding of these topics.
They are:
Static Fields & Methods
Loops & Iterators
Using Dates & Calendars
If & Switch Statements
File Navigation & I/O
Polymorphism - Method Overloading and Method Overriding
Encapsulation
Inheritance
Arithmetic Operators
Logical Operators
Questions:
51. Are true and false keywords?
The values true and false are not keywords.
52. What is a void return type?
A void return type indicates that a method does not return a value after its execution.
53. What is the difference between the File and RandomAccessFile classes?
The File class encapsulates the files and directories of the local file system. The RandomAccessFile class provides the methods needed to directly access data contained in any part of a file.
54. Which package is always imported by default?
The java.lang package is always imported by default in all Java Classes.
55. What restrictions are placed on method overriding?
Overridden methods must have the same name, argument list, and return type. The overriding method may not limit the access of the method it overrides but it can expand it. The overriding method may not throw any exceptions that are not thrown by the overridden method.
56. Which arithmetic operations can result in the throwing of an ArithmeticException?
Integer / and % can result in the throwing of an ArithmeticException.
57. What is the ResourceBundle class?
The ResourceBundle class is used to store locale-specific resources that can be loaded by a program to tailor the program's appearance to the particular locale in which it is being run.
58. What is numeric promotion?
Numeric promotion is the conversion of a smaller numeric type to a larger numeric type, so that integer and floating-point operations may take place. In numerical promotion, byte, char, and short values are converted to int values. The int values are also converted to long values, if necessary. The long and float values are converted to double values, as required.
59. To what value is a variable of the boolean type automatically initialized?
The default value of the boolean type is false.
60. What is the difference between the prefix and postfix forms of the ++ operator?
The prefix form performs the increment operation and returns the value of the increment operation. The postfix form returns the current value to the expression and then performs the increment operation on that value.
61. What is the purpose of a statement block?
A statement block is used to organize a sequence of statements as a single statement group.
62. What is the difference between an if statement and a switch statement?
The if statement is used to select among two alternatives. It uses a boolean expression to decide which alternative should be executed. The switch statement is used to select among multiple alternatives. It uses an int expression to determine which alternative should be executed.
A Switch statement with 5 Case blocks can be compared to an if statement with 5 else-if blocks.
63. What do you mean by object oreiented programming
In object oreinted programming the emphasis is more on data than on the procedure and the program is divided into objects. Some concepts in OO Programming are:
* The data fields are hidden and they cant be accessed by external functions.
* The design approach is bottom up.
* The Methods operate on data that is tied together in data structure
64. What are 4 pillars of object oreinted programming
1. Abstraction - It means hiding the details and only exposing the essentioal parts
2. Polymorphism - Polymorphism means having many forms. In java you can see polymorphism when you have multiple methods with the same name
3. Inheritance - Inheritance means the child class inherits the non private properties of the parent class
4. Encapsulation - It means data hiding. In java with encapsulate the data by making it private and even we want some other class to work on that data then the setter and getter methods are provided
65. Difference between procedural and object oreinted language
In procedural programming the instructions are executed one after another and the data is exposed to the whole program
In Object Oriented programming the unit of program is an object which is nothing but combination of data and code and the data is not exposed outside the object
66. What is the difference between parameters and arguments
While defining method, variables passed in the method are called parameters. While using those methods, values passed to those variables are called arguments.
67. What is reflection in java
Reflection allows Java code to discover information about the fields, methods and constructors of loaded classes and to dynamically invoke them. The Java Reflection API covers the Reflection features.
68. What is a cloneable interface and how many methods does it contain
The cloneable interface is used to identify objects that can be cloned using the Object.clone() method. IT is a Tagged or a Marker Interface and hence it does not have any methods.
69. What is the difference between Java Bean and Java Class
Basically a Bean is a java class but it has getter and setter method and it does not have any logic in it, it is used for holding data.
On the other hand the Java class can have what a java bean has and also has some logic inside it
70. What are null or Marker interfaces in Java
The null interfaces or marker interfaces or Tagged Interfaces, do not have method declarations in them. They are empty interfaces, this is to convey the compiler that they have to be treated differently
71. Does java Support multiple inheritance
Java does not support multiple inheritance directly like C++, because then it is prone to ambiguity, example if a class extends 2 other classes and these 2 parent classes have same method names then there is ambiguity. Hence in Partial Java Multiple inheritance is supported using Interfaces
72. What are virtual function
In OOP when a derived class inherits from a base class, an object of the derived class may be referred to (or cast) as either being the base class type or the derived class type. If there are base class functions overridden by the derived class, a problem then arises when a derived object has been cast as the base class type. When a derived object is referred to as being of the base's type, the desired function call behavior is ambiguous.
The distinction between virtual and not virtual is provided to solve this issue. If the function in question is designated "virtual" then the derived class's function would be called (if it exists). If it is not virtual, the base class's function would be called.
73. Does java support virtual functions
No java does not support virtual functions direclty like in C++, but it supports using Abstract class and interfaces
74. What is JVM
When we install a java package. It contains 2 things
* The Java Runtime Environment (JRE)
* The Java Development Kit (JDK)
The JRE provides runtime support for Java applications. The JDK provides the Java compiler and other development tools. The JDK includes the JRE.
Both the JRE and the JDK include a Java Virtual Machine (JVM). This is the application that executes a Java program. A Java program requires a JVM to run on a particular platform
75. What is the difference between Authentication and Authorization
Authentication is a process for verifying that an individual is who they say they are. Authorization is an additional level of security, and it means that a particular user (usually authenticated), may have access to a particular resource say record, file, directory or script.
76. What types of values does boolean variables take
It only takes values true and false.
77. Which primitive datatypes are signed.
All primitive datatypes are signed except char and Boolean
78. Is char type signed or unsigned
char type is integral but unsigned. It range is 0 to 2^7-1
79. What forms an integral literal can be
decimal, octal and hexadecimal, hence example it can be 28, 034 and 0x1c respectively
80. Why is the main method static
So that it can be invoked without creating an instance of that class
81. What is the difference between class variable, member variable and automatic(local) variable
class variable is a static variable and does not belong to instance of class but rather shared across all the instances of the Class.
member variable belongs to a particular instance of class and can be called from any method of the class
automatic or local variable is created on entry to a method and is alive only when the method is executed
82. When are static and non static variables of the class initialized
The static variables are initialized when the class is loaded
Non static variables are initialized just before the constructor is called
83. How is an argument passed in java, is it by copy or by reference?
If the variable is primitive datatype then it is passed by copy.
If the variable is an object then it is passed by reference
84. How does bitwise (~) operator work
It converts all the 1 bits in a binary value to 0s and all the 0 bits to 1s, e.g 11110000 gets coverted to 00001111
85. Can shift operators be applied to float types.
No, shift operators can be applied only to integer or long types (whole numbers)
86. What happens to the bits that fall off after shifting
They are discarded (ignored)
87. What are the rules for overriding
The rules for Overriding are:
Private method can be overridden by private, protected or public methods
Friendly method can be overridden by protected or public methods
Protected method can be overridden by protected or public methods
Public method can be overridden by public method
88. Explain the final Modifier
Final can be applied to classes, methods and variables and the features cannot be changed. Final class cannot be subclassed, methods cannot be overridden
89. Can you change the reference of the final object
No the reference cannot be changed, but the data in that object can be changed
90. Can abstract modifier be applied to a variable
No it can be applied only to class and methods
91. Where can static modifiers be used
They can be applied to variables, methods and even a block of code, static methods and variables are not associated with any instance of class
92. When are the static variables loaded into the memory
During the class load time
93. When are the non static variables loaded into the memory
They are loaded just before the constructor is called
94. How can you reference static variables
You can refer to static variables directly using the class name and you dont need any object instance for it.
Ex: ClassTest.execMethod(); can be used to access the execMethod() method of the class ClassTest
95. Can static method use non static features of there class
No they are not allowed to use non static features of the class, they can only call static methods and can use static data
96. What is static initializer code
A class can have a block of initializer code that is simply surrounded by curly braces and labeled as static e.g.
public class Test{
static int =10;
static{
System.out.println("Hiiiiiii");
}
}
And this code is executed exactly once at the time of class load
97. Where is native modifier used?
It can refer only to methods and it indicates that the body of the method is to be found else where and it is usually written in language other than Java.
98. When do you use continue and when do you use break statements
When continue statement is applied it prematurely completes the iteration of a loop.
When break statement is applied it causes the entire loop to be abandoned.
99. What do you understand by late binding or virtual method Invocation.
When a compiler for a non object oriented language comes across a method invocation, it determines exactly what target code should be called and build machine language to represent that call. In an object oriented language, this is not possible since the proper code to invoke is determined based upon the class if the object being used to make the call, not the type of the variable. Instead code is generated that will allow the decision to be made at run time. This delayed decision making is called as late binding
100. Can Overridden methods have different return types
No they cannot have different return types
101. If the method to be overridden has access type protected, can subclass have the access type as private
No, it must have access type as protected or public, since an overriding method must not be less accessible than the method it overrides
102. What are the Final fields & Final Methods ?
Fields and methods can also be declared final. A final method cannot be overridden in a subclass. A final field is like a constant: once it has been given a value, it cannot be assigned again.
If you have any questions that you want answer for - please leave a comment on this page and I will answer them.
If you have any more questions on Other Java Topics that you have faced during your interviews and wish to add them to this collection - pls drop a note to [email protected] and I shall be glad to add them to this list.
Previous Set of Core Java Interview Questions - Part 1
Other Java & J2EE Interview Questions
Topics Covered in the Blog - Synopsis
Showing posts with label Java. Show all posts
Showing posts with label Java. Show all posts
Tuesday, April 19, 2011
Friday, January 28, 2011
Chapter 15: Stack and Heap
You might be wondering, is Stack and Heap such a large topic that I have dedicated one full chapter to it? Actually it isnt such a big topic but it is extremely important to understand them fully and clearly in order to grasp the forthcoming topics clearly. And combining this with any other topic would make it a bit confusing or rather off-place. So it is given a separate topic status. (We will be touching about these as and when required in the forthcoming chapters and this chapter would just be a quick overview)
For the most part, the various pieces (methods, variables, and objects) of Java programs live in one of two places in memory: either the stack or the heap. For now, let us worry about only three types of things: instance variables, local variables, and objects:
• Instance variables and objects live on the heap.
• Local variables live on the stack.
Let’s take a look at a Java program, and how its various pieces are created and map into the stack and the heap:
1. class Maine { }
2.
3. class Lion {
4. Maine c; // instance variable
5. String name; // instance variable
6.
7. public static void main(String [] args) {
8.
9. Lion d; // local variable: d
10. d = new Lion();
11. d.go(d);
12. }
13. void go(Lion Lion) { // local variable: Lion
14. c = new Maine();
15. Lion.setName("Aiko");
16. }
17. void setName(String LionName) { // local var: LionName
18. name = LionName;
19. // do more stuff
20. }
21. }
This is how the variables and methods get placed in the stack and heap during execution of the above piece of code.
• Line 7—main() is placed on the stack.
• Line 9—reference variable d is created on the stack, but there’s no Lion object yet.
• Line 10—a new Lion object is created and is assigned to the d reference variable.
• Line 11—a copy of the reference variable d is passed to the go() method.
• Line 13—the go() method is placed on the stack, with the Lion parameter as a local variable.
• Line 14—a new Maine object is created on the heap, and assigned to Lion’s instance variable.
• Line 17—setName() is added to the stack, with the LionName parameter as its local variable.
• Line 18—the name instance variable now also refers to the String object.
• Notice that two different local variables refer to the same Lion object.
• Notice that one local variable and one instance variable both refer to the same String Aiko.
• After Line 19 completes, setName() completes and is removed from the stack. At this point the local variable LionName disappears too, although the String object it referred to is still on the heap.
Previous Chapter: Self Test - Chapters 6 to 14
Next Chapter: Chapter 16: Literals, Assignments and Variables
For the most part, the various pieces (methods, variables, and objects) of Java programs live in one of two places in memory: either the stack or the heap. For now, let us worry about only three types of things: instance variables, local variables, and objects:
• Instance variables and objects live on the heap.
• Local variables live on the stack.
Let’s take a look at a Java program, and how its various pieces are created and map into the stack and the heap:
1. class Maine { }
2.
3. class Lion {
4. Maine c; // instance variable
5. String name; // instance variable
6.
7. public static void main(String [] args) {
8.
9. Lion d; // local variable: d
10. d = new Lion();
11. d.go(d);
12. }
13. void go(Lion Lion) { // local variable: Lion
14. c = new Maine();
15. Lion.setName("Aiko");
16. }
17. void setName(String LionName) { // local var: LionName
18. name = LionName;
19. // do more stuff
20. }
21. }
This is how the variables and methods get placed in the stack and heap during execution of the above piece of code.
• Line 7—main() is placed on the stack.
• Line 9—reference variable d is created on the stack, but there’s no Lion object yet.
• Line 10—a new Lion object is created and is assigned to the d reference variable.
• Line 11—a copy of the reference variable d is passed to the go() method.
• Line 13—the go() method is placed on the stack, with the Lion parameter as a local variable.
• Line 14—a new Maine object is created on the heap, and assigned to Lion’s instance variable.
• Line 17—setName() is added to the stack, with the LionName parameter as its local variable.
• Line 18—the name instance variable now also refers to the String object.
• Notice that two different local variables refer to the same Lion object.
• Notice that one local variable and one instance variable both refer to the same String Aiko.
• After Line 19 completes, setName() completes and is removed from the stack. At this point the local variable LionName disappears too, although the String object it referred to is still on the heap.
Previous Chapter: Self Test - Chapters 6 to 14
Next Chapter: Chapter 16: Literals, Assignments and Variables
Labels:
heap,
heaps,
Java,
java heap,
java stack,
SCJP,
SCJP Certification,
stack,
stacks,
stacks and heaps
| Reactions: |
Wednesday, January 26, 2011
Chapter 14: Coupling and Cohesion
You would have heard or learnt a lot about coupling and cohesion when you learnt object oriented concepts or while learning other programming languages like c++. Let me tell you up front that, this chapter is going to be from the SCJP exam perspective and is going to cover concepts related to these two topics only from the exam point of you and not the overall dig deep into the topics. Frankly speaking, you’ll have very few questions about coupling and cohesion on the real exam.
Lets get started.
These two topics, coupling and cohesion, have to do with the quality of an OO design. In general, good OO design calls for loose coupling and shuns tight coupling, and good OO design calls for high cohesion, and shuns low cohesion. As with most OO design discussions, the goals for an application are
• Ease of creation
• Ease of maintenance
• Ease of enhancement
Coupling
Coupling is the degree to which one class knows about another class. If the only knowledge that class A has about class B, is what class B has exposed through its interface, then class A and class B are said to be loosely coupled. If, on the other hand, class A relies on parts of class B that are not part of class B’s interface, then the coupling between the classes is tighter. In other words, if A knows more than it should about the way in which B was implemented, then A and B are tightly coupled.
Using this second scenario, imagine what happens when class B is enhanced. It’s quite possible that the developer enhancing class B has no knowledge of class A, (why would he/she?) Class B’s developer ought to feel that any enhancements that don’t break the class’s interface should be safe, so she might change some non-interface parts of the class, which then causes class A to break.
At the far end of the coupling spectrum is the horrible situation in which class A knows non-API stuff about class B, and class B knows non-API stuff about class A. (This is REALLY BAD CODING). If either class is ever changed, there’s a chance that the other class will break. Let’s look at an obvious example of tight coupling, which has been enabled by poor encapsulation:
class CalculateTaxes {
float rate;
float doIndia() {
TaxRatesInIndia str = new TaxRatesInIndia();
rate = str.salesRate; // ouch
// this should be a method call:
// rate = str.getSalesTaxRates("CO");
// do stuff with rate
}
}
class TaxRatesInIndia {
public float salesRate; // should be private
public float adjustedSalesRate; // should be private
public float getSalesTaxRates(String region) {
salesRate = new CalculateTaxes().doIndia(); // ouch again!
// do country-based calculations
return adjustedSalesRate;
}
}
All large OO applications are a mix of many classes and interfaces working together. Ideally, all interactions between objects in an OO system should use the APIs, in other words, the contracts, of the objects’ respective classes. Theoretically, if all of the classes in an application have well-designed APIs, then it should be possible for all interclass interactions to use those APIs exclusively. If you make changes to the way one class behaves, in a loosely coupled environment, you shouldn't be getting surprise errors in other classes. As we discussed earlier in this chapter, an aspect of good class and API design is that classes should be well encapsulated.
The point here is that coupling is a somewhat subjective concept. Because of this, the SCJP exam will test you on really obvious examples of tight coupling only. So don't worry much about having to make design decisions about code.
Cohesion
While coupling has to do with how classes interact with each other, cohesion is all about how a single class is designed. The term cohesion is used to indicate the degree to which a class has a single, well-focused purpose. Keep in mind that cohesion too is a subjective concept. The more focused a class is, the higher its cohesiveness. The key benefit of high cohesion is that such classes are typically much easier to maintain (and less frequently changed) than classes with low cohesion. Another benefit of high cohesion is that classes with a well-focused purpose tend to be more reusable than other classes. Let’s take a look at a pseudocode example:
class SalesReport {
void connectToDb(){ }
void generateSalesReport() { }
void saveAsFile() { }
void print() { }
}
Now imagine your manager comes along and says, “Hey you know that accounting application we’re working on? The clients just decided that they’re also going to want to generate a revenue projection report, oh and they want to do some inventory reporting also. They do like our reporting features however, so make sure that all of these reports will let them choose a database, choose a printer, and save generated reports to data files...”
Rather than putting all the printing code into one report class, we probably would have been better off with the following design right from the start:
class SalesReport {
Options getReportingOptions() { }
void generateSalesReport(Options o) { }
}
class ConnectToDb {
DBconnection getDb() { }
}
class PrintStuff {
PrintOptions getPrintOptions() { }
}
class FileSaver {
SaveOptions getFileSaveOptions() { }
}
This design is much more cohesive. Instead of one class that does everything, we’ve broken the system into four main classes, each with a very specific, or cohesive, role. Because we’ve built these specialized, reusable classes, it’ll be much easier to write a new report, since we’ve already got the database connection class, the printing class, and the file saver class, and that means they can be reused by other classes that might want to print a report. Again, as in Coupling, you may not get too many questions about cohesion but if you are (un)lucky you may get one or two…
Previous Chapter: Chapter 13: Statics
Next Chapter: Quick Review: Chapters 6 to 14
Lets get started.
These two topics, coupling and cohesion, have to do with the quality of an OO design. In general, good OO design calls for loose coupling and shuns tight coupling, and good OO design calls for high cohesion, and shuns low cohesion. As with most OO design discussions, the goals for an application are
• Ease of creation
• Ease of maintenance
• Ease of enhancement
Coupling
Coupling is the degree to which one class knows about another class. If the only knowledge that class A has about class B, is what class B has exposed through its interface, then class A and class B are said to be loosely coupled. If, on the other hand, class A relies on parts of class B that are not part of class B’s interface, then the coupling between the classes is tighter. In other words, if A knows more than it should about the way in which B was implemented, then A and B are tightly coupled.
Using this second scenario, imagine what happens when class B is enhanced. It’s quite possible that the developer enhancing class B has no knowledge of class A, (why would he/she?) Class B’s developer ought to feel that any enhancements that don’t break the class’s interface should be safe, so she might change some non-interface parts of the class, which then causes class A to break.
At the far end of the coupling spectrum is the horrible situation in which class A knows non-API stuff about class B, and class B knows non-API stuff about class A. (This is REALLY BAD CODING). If either class is ever changed, there’s a chance that the other class will break. Let’s look at an obvious example of tight coupling, which has been enabled by poor encapsulation:
class CalculateTaxes {
float rate;
float doIndia() {
TaxRatesInIndia str = new TaxRatesInIndia();
rate = str.salesRate; // ouch
// this should be a method call:
// rate = str.getSalesTaxRates("CO");
// do stuff with rate
}
}
class TaxRatesInIndia {
public float salesRate; // should be private
public float adjustedSalesRate; // should be private
public float getSalesTaxRates(String region) {
salesRate = new CalculateTaxes().doIndia(); // ouch again!
// do country-based calculations
return adjustedSalesRate;
}
}
All large OO applications are a mix of many classes and interfaces working together. Ideally, all interactions between objects in an OO system should use the APIs, in other words, the contracts, of the objects’ respective classes. Theoretically, if all of the classes in an application have well-designed APIs, then it should be possible for all interclass interactions to use those APIs exclusively. If you make changes to the way one class behaves, in a loosely coupled environment, you shouldn't be getting surprise errors in other classes. As we discussed earlier in this chapter, an aspect of good class and API design is that classes should be well encapsulated.
The point here is that coupling is a somewhat subjective concept. Because of this, the SCJP exam will test you on really obvious examples of tight coupling only. So don't worry much about having to make design decisions about code.
Cohesion
While coupling has to do with how classes interact with each other, cohesion is all about how a single class is designed. The term cohesion is used to indicate the degree to which a class has a single, well-focused purpose. Keep in mind that cohesion too is a subjective concept. The more focused a class is, the higher its cohesiveness. The key benefit of high cohesion is that such classes are typically much easier to maintain (and less frequently changed) than classes with low cohesion. Another benefit of high cohesion is that classes with a well-focused purpose tend to be more reusable than other classes. Let’s take a look at a pseudocode example:
class SalesReport {
void connectToDb(){ }
void generateSalesReport() { }
void saveAsFile() { }
void print() { }
}
Now imagine your manager comes along and says, “Hey you know that accounting application we’re working on? The clients just decided that they’re also going to want to generate a revenue projection report, oh and they want to do some inventory reporting also. They do like our reporting features however, so make sure that all of these reports will let them choose a database, choose a printer, and save generated reports to data files...”
Rather than putting all the printing code into one report class, we probably would have been better off with the following design right from the start:
class SalesReport {
Options getReportingOptions() { }
void generateSalesReport(Options o) { }
}
class ConnectToDb {
DBconnection getDb() { }
}
class PrintStuff {
PrintOptions getPrintOptions() { }
}
class FileSaver {
SaveOptions getFileSaveOptions() { }
}
This design is much more cohesive. Instead of one class that does everything, we’ve broken the system into four main classes, each with a very specific, or cohesive, role. Because we’ve built these specialized, reusable classes, it’ll be much easier to write a new report, since we’ve already got the database connection class, the printing class, and the file saver class, and that means they can be reused by other classes that might want to print a report. Again, as in Coupling, you may not get too many questions about cohesion but if you are (un)lucky you may get one or two…
Previous Chapter: Chapter 13: Statics
Next Chapter: Quick Review: Chapters 6 to 14
Labels:
cohesion,
coupling,
Encapsulation,
inheritance,
Java,
loosely coupled,
SCJP,
SCJP Certification,
tightly coupled
| Reactions: |
Tuesday, January 25, 2011
Chapter 13: Statics
Static is one of the most important and powerful keywords in the java programming language. It can alter the behavior of variables and methods. The purpose of this chapter is to take a detailed look at this feature.
Static Variables and Methods
The static modifier has such a profound impact on the behavior of a method or variable that we’re treating it as a concept entirely separate from the other modifiers. To understand the way a static member works, we’ll look first at a reason for using one. Imagine you’ve got a utility class with a method that always runs the same way; its sole function is to return, say, a random number. It wouldn’t matter which instance of the class performed the method—it would always behave exactly the same way. In other words, the method’s behavior has no dependency on the state (instance variable values) of an object. So why, then, do you need an object when the method will never be instance-specific? Why not just ask the class itself to run the method?
Let’s imagine another scenario: Suppose you want to keep a running count of all instances instantiated from a particular class. Where do you actually keep that variable? It won’t work to keep it as an instance variable within the class whose instances you’re tracking, because the count will just be initialized back to a default value with each new instance. The answer to both the utility-method-always-runs-the-same scenario and the keep-a-running-total-of-instances scenario is to use the static modifier. Variables and methods marked static belong to the class, rather than to any particular instance. In fact, you can use a static method or variable without having any instances of that class at all. You need only have the class available to be able to invoke a static method or access a static variable. static variables, too, can be accessed without having an instance of a class. But if there are instances, a static variable of a class will be shared by all instances of that class; there is only one copy.
The following code declares and uses a static counter variable:
class Car {
static int CarCount = 0; // Declare and initialize
// static variable
public Car() {
CarCount += 1; // Modify the value in the constructor
}
public static void main (String [] args) {
new Car();
new Car();
new Car();
System.out.println("Car count is now " + CarCount);
}
}
In the preceding code, the static CarCount variable is set to zero when the Car class is first loaded by the JVM, before any Car instances are created! (By the way, you don’t actually need to initialize a static variable to zero; static variables get the same default values instance variables get.) Whenever a Car instance is created, the Car constructor runs and increments the static CarCount variable. When this code executes, three Car instances are created in main(), and the result is
Car count is now 3
Now imagine what would happen if CarCount were an instance variable (in other words, nonstatic):
class Car {
int CarCount = 0; // Declare and initialize
// instance variable
public Car() {
CarCount += 1; // Modify the value in the constructor
}
public static void main (String [] args) {
new Car();
new Car();
new Car();
System.out.println("Car count is now " + CarCount);
}
}
When this code executes, it should still create three Car instances in main(), but the result is...a compiler error! We can’t get this code to compile, let alone run.
Car.java:11: nonstatic variable CarCount cannot be referenced
from a static context
System.out.println("Car count is " + CarCount);
^
1 error
The JVM doesn’t know which Car object’s CarCount you’re trying to access. The problem is that main() is itself a static method, and thus isn’t running against any particular instance of the class, rather just on the class itself. A static method can’t access a nonstatic (instance) variable, because there is no instance! That’s not to say there aren’t instances of the class alive on the heap, but rather that even if there are, the static method doesn’t know anything about them. The same applies to instance methods; a static method can’t directly invoke a nonstatic method. Think static = class, nonstatic = instance. Making the method called by the JVM (main()) a static method means the JVM doesn’t have to create an instance of your class just to start running code.
Exam Tip:
Accessing Static Methods and Variables
Since you don’t need to have an instance in order to invoke a static method or access a static variable, then how do you invoke or use a static member? What’s the syntax? We know that with a regular old instance method, you use the dot operator on a reference to an instance:
class Car {
int CarSize = 0;
public int getCarSize() {
return CarSize;
}
public Car(int s) {
CarSize = s;
}
public static void main (String [] args) {
Car f = new Car(25);
System.out.println(f.getCarSize()); // Access instance
// method using f
}
}
In the preceding code, we instantiate a Car, assign it to the reference variable f, and then use that f reference to invoke a method on the Car instance we just created. In other words, the getCarSize() method is being invoked on a specific Car object on the heap.
But this approach (using a reference to an object) isn’t appropriate for accessing a static method, because there might not be any instances of the class at all! So, the way we access a static method (or static variable) is to use the dot operator on the class name, as opposed to using it on a reference to an instance, as follows:
class Car {
static int CarCount = 0; // Declare and initialize
// static variable
public Car() {
CarCount += 1; // Modify the value in the constructor
}
}
class TestCar {
public static void main (String [] args) {
new Car();
new Car();
new Car();
System.out.print("CarCount:"+Car.CarCount); //Access
// static variable
}
}
But just to make it really confusing, the Java language also allows you to use an object reference variable to access a static member:
Car f = new Car();
int Cars = f.CarCount; // Access static variable
// CarCount using f
In the preceding code, we instantiate a Car, assign the new Car object to the reference variable f, and then use the f reference to invoke a static method! But even though we are using a specific Car instance to access the static method, the rules haven’t changed. This is merely a syntax trick to let you use an object reference variable (but not the object it refers to) to get to a static method or variable, but the static member is still unaware of the particular instance used to invoke the static member. In the Car example, the compiler knows that the reference variable f is of type Car, and so the Car class static method is run with no awareness or concern for the Car instance at the other end of the f reference. In other words, the compiler cares only that reference variable f is declared as type Car.
Finally, remember that static methods can’t be overridden! This doesn’t mean they can’t be redefined in a subclass, but redefining and overriding isn’t the same thing. Let’s take a look at an example of a redefined (remember, not overridden), static method:
class Car {
static void drive() {
System.out.print("a ");
}
}
class Ferrari extends Car {
static void drive() { // it's a redefinition & not an override
System.out.print("d ");
}
public static void main(String [] args) {
Car [] a = {new Car(), new Ferrari(), new Car()};
for(int x = 0; x < a.length; x++) a[x].drive(); // invoke the static method } } Running this code produces the output: a a a Remember, the syntax a[x].drive() is just a shortcut (the syntax trick)...the compiler is going to substitute something like Car.drive() instead. This happens because the Array is of type Car and so the static method inside the Car class is used even though there is an instance of Ferrari in the list. Previous Chapter: Chapter 12 - Constructors and Instantiation
Next Chapter: Chapter 13 - Coupling & Cohesion
Static Variables and Methods
The static modifier has such a profound impact on the behavior of a method or variable that we’re treating it as a concept entirely separate from the other modifiers. To understand the way a static member works, we’ll look first at a reason for using one. Imagine you’ve got a utility class with a method that always runs the same way; its sole function is to return, say, a random number. It wouldn’t matter which instance of the class performed the method—it would always behave exactly the same way. In other words, the method’s behavior has no dependency on the state (instance variable values) of an object. So why, then, do you need an object when the method will never be instance-specific? Why not just ask the class itself to run the method?
Let’s imagine another scenario: Suppose you want to keep a running count of all instances instantiated from a particular class. Where do you actually keep that variable? It won’t work to keep it as an instance variable within the class whose instances you’re tracking, because the count will just be initialized back to a default value with each new instance. The answer to both the utility-method-always-runs-the-same scenario and the keep-a-running-total-of-instances scenario is to use the static modifier. Variables and methods marked static belong to the class, rather than to any particular instance. In fact, you can use a static method or variable without having any instances of that class at all. You need only have the class available to be able to invoke a static method or access a static variable. static variables, too, can be accessed without having an instance of a class. But if there are instances, a static variable of a class will be shared by all instances of that class; there is only one copy.
The following code declares and uses a static counter variable:
class Car {
static int CarCount = 0; // Declare and initialize
// static variable
public Car() {
CarCount += 1; // Modify the value in the constructor
}
public static void main (String [] args) {
new Car();
new Car();
new Car();
System.out.println("Car count is now " + CarCount);
}
}
In the preceding code, the static CarCount variable is set to zero when the Car class is first loaded by the JVM, before any Car instances are created! (By the way, you don’t actually need to initialize a static variable to zero; static variables get the same default values instance variables get.) Whenever a Car instance is created, the Car constructor runs and increments the static CarCount variable. When this code executes, three Car instances are created in main(), and the result is
Car count is now 3
Now imagine what would happen if CarCount were an instance variable (in other words, nonstatic):
class Car {
int CarCount = 0; // Declare and initialize
// instance variable
public Car() {
CarCount += 1; // Modify the value in the constructor
}
public static void main (String [] args) {
new Car();
new Car();
new Car();
System.out.println("Car count is now " + CarCount);
}
}
When this code executes, it should still create three Car instances in main(), but the result is...a compiler error! We can’t get this code to compile, let alone run.
Car.java:11: nonstatic variable CarCount cannot be referenced
from a static context
System.out.println("Car count is " + CarCount);
^
1 error
The JVM doesn’t know which Car object’s CarCount you’re trying to access. The problem is that main() is itself a static method, and thus isn’t running against any particular instance of the class, rather just on the class itself. A static method can’t access a nonstatic (instance) variable, because there is no instance! That’s not to say there aren’t instances of the class alive on the heap, but rather that even if there are, the static method doesn’t know anything about them. The same applies to instance methods; a static method can’t directly invoke a nonstatic method. Think static = class, nonstatic = instance. Making the method called by the JVM (main()) a static method means the JVM doesn’t have to create an instance of your class just to start running code.
Exam Tip:
One of the mistakes most often made by new Java programmers is attempting to access an instance variable (which means nonstatic variable) from the static main() method (which doesn’t know anything about any instances, so it can’t access the variable). The following code is an example of illegal access of a nonstatic variable from a static method:
class Bad {
int x = 3;
public static void main (String [] args) {
System.out.println("x is " + x);
}
}
Understand that this code will never compile, because you can’t access a nonstatic (instance) variable from a static method. Just think of the compiler saying, “Hey, I have no idea which Bad object’s x variable you’re trying to print!” Remember, it’s the class running the main() method, not an instance of the class.
Of course, the tricky part for the exam is that the question won’t look as obvious as the preceding code. The problem you’re being tested for—accessing a nonstatic variable from a static method—will be buried in code that might appear to be testing something else. For example, the preceding code would be more likely to appear as
class Bad {
int x = 3;
float y = 4.3f;
public static void main (String [] args) {
for (int z = x; z < ++x; z--, y = y + z) // complicated looping and branching code } } So while you’re trying to follow the logic, the real issue is that x and y can’t be used within main(), because x and y are instance, not static, variables! The same applies for accessing nonstatic methods from a static method. The rule is, a static method of a class can’t access a nonstatic (instance) method or variable of its own class.
Accessing Static Methods and Variables
Since you don’t need to have an instance in order to invoke a static method or access a static variable, then how do you invoke or use a static member? What’s the syntax? We know that with a regular old instance method, you use the dot operator on a reference to an instance:
class Car {
int CarSize = 0;
public int getCarSize() {
return CarSize;
}
public Car(int s) {
CarSize = s;
}
public static void main (String [] args) {
Car f = new Car(25);
System.out.println(f.getCarSize()); // Access instance
// method using f
}
}
In the preceding code, we instantiate a Car, assign it to the reference variable f, and then use that f reference to invoke a method on the Car instance we just created. In other words, the getCarSize() method is being invoked on a specific Car object on the heap.
But this approach (using a reference to an object) isn’t appropriate for accessing a static method, because there might not be any instances of the class at all! So, the way we access a static method (or static variable) is to use the dot operator on the class name, as opposed to using it on a reference to an instance, as follows:
class Car {
static int CarCount = 0; // Declare and initialize
// static variable
public Car() {
CarCount += 1; // Modify the value in the constructor
}
}
class TestCar {
public static void main (String [] args) {
new Car();
new Car();
new Car();
System.out.print("CarCount:"+Car.CarCount); //Access
// static variable
}
}
But just to make it really confusing, the Java language also allows you to use an object reference variable to access a static member:
Car f = new Car();
int Cars = f.CarCount; // Access static variable
// CarCount using f
In the preceding code, we instantiate a Car, assign the new Car object to the reference variable f, and then use the f reference to invoke a static method! But even though we are using a specific Car instance to access the static method, the rules haven’t changed. This is merely a syntax trick to let you use an object reference variable (but not the object it refers to) to get to a static method or variable, but the static member is still unaware of the particular instance used to invoke the static member. In the Car example, the compiler knows that the reference variable f is of type Car, and so the Car class static method is run with no awareness or concern for the Car instance at the other end of the f reference. In other words, the compiler cares only that reference variable f is declared as type Car.
Finally, remember that static methods can’t be overridden! This doesn’t mean they can’t be redefined in a subclass, but redefining and overriding isn’t the same thing. Let’s take a look at an example of a redefined (remember, not overridden), static method:
class Car {
static void drive() {
System.out.print("a ");
}
}
class Ferrari extends Car {
static void drive() { // it's a redefinition & not an override
System.out.print("d ");
}
public static void main(String [] args) {
Car [] a = {new Car(), new Ferrari(), new Car()};
for(int x = 0; x < a.length; x++) a[x].drive(); // invoke the static method } } Running this code produces the output: a a a Remember, the syntax a[x].drive() is just a shortcut (the syntax trick)...the compiler is going to substitute something like Car.drive() instead. This happens because the Array is of type Car and so the static method inside the Car class is used even though there is an instance of Ferrari in the list. Previous Chapter: Chapter 12 - Constructors and Instantiation
Next Chapter: Chapter 13 - Coupling & Cohesion
Labels:
Java,
SCJP,
SCJP Certification,
static,
static declaration,
static method,
Static variable
| Reactions: |
Chapter 12: Constructors and Instantiation
Objects are constructed. You can’t make a new object without invoking a constructor. In fact, you can’t make a new object without invoking not just the constructor of the object’s actual class type, but also the constructor of each of its superclasses including the Object class itself! Constructors are the code that runs whenever you use the keyword new. To be a bit more accurate, there can also be initialization blocks that run when you say new (init blocks), but we’re going to cover them, and their static initialization counterparts, in the next chapter.
We already have a lot to discuss here. So let’s get started.
Constructor Basics
Every class, including abstract classes, MUST have a constructor. Hard Code that into your brain. But just because a class must have one, doesn’t mean the programmer has to type it. A constructor looks like this:
class Car {
Car() { } // The constructor for the Car class
}
You notice anything missing in the declaration above? There’s no return type! Two key points to remember about constructors are that they have no return type and their names must exactly match the class name. Typically, constructors are used to initialize instance variable state, as follows:
class Car {
int size;
String name;
Car(String name, int size) {
this.name = name;
this.size = size;
}
}
In the preceding code example, the Car class does not have a no-arg constructor. That means the following will fail to compile:
Car f = new Car(); // Won't compile, no matching constructor
but the following will compile:
Car f = new Car("Ford", 43); // No problem. Arguments match
// the Car constructor.
So it’s very common for a class to have a no-arg constructor, regardless of how many other overloaded constructors are in the class (constructors can be overloaded just like methods). You can’t always make that work for your classes; occasionally you have a class where it makes no sense to create an instance without supplying information to the constructor. A java.awt.Color object, for example, can’t be created by calling a no-arg constructor, because that would be like saying to the JVM, “Make me a new Color object, and I really don’t care what color it is....” Do you seriously want the JVM making your color choices?
Constructor Chaining
We know that constructors are invoked at runtime when you say new on some class type as follows:
Lamborghini h = new Lamborghini();
But what really happens when you say new Lamborghini() ? (Assume Lamborghini extends Car and Car extends Object.)
1. Lamborghini constructor is invoked. Every constructor invokes the constructor of its superclass with an (implicit) call to super(),
2. Car constructor is invoked (Car is the superclass of Lamborghini).
3. Object constructor is invoked (Object is the ultimate superclass of all classes, so class Car extends Object even though you don’t actually type “extends Object” into the Car class declaration. It’s implicit.) At this point we’re on the top of the hierarchy.
4. Object instance variables are given their explicit values. By explicit values, we mean values that are assigned at the time the variables are declared, like “int x = 27”, where “27” is the explicit value (as opposed to the default value) of the instance variable.
5. Object constructor completes.
6. Car instance variables are given their explicit values (if any).
7. Car constructor completes.
8. Lamborghini instance variables are given their explicit values (if any).
9. Lamborghini constructor completes.
Rules for Constructors
The following list summarizes the rules you’ll need to know about Constructors. There are very important and you MUST remember these to answer the questions related to Constructors in the SCJP Exam.
• Constructors can use any access modifier, including private. (We will deal with private constructors in one of the later chapters)
• The constructor name must match the name of the class. (100% Case Sensitive)
• Constructors must not have a return type.
• It’s legal (but probably stupid) to have a method with the same name as the class, but that doesn’t make it a constructor. If you see a return type, it’s a method and not a constructor. In fact, you could have both a method and a constructor with the same name—the name of the class—in the same class, and that’s not a problem for Java. Be careful not to mistake a method for a constructor—be sure to look for a return type.
• If you don’t type a constructor into your class code, a default constructor will be automatically generated by the compiler.
• The default constructor is ALWAYS a no-arg constructor. (Obviously the compiler has no clue what all arguments you might want for your class. So it takes the safe way out with a no argument constructor)
• If you want a no-arg constructor and you’ve typed any other constructor(s) into your class code, the compiler won’t provide the no-arg constructor (or any other constructor) for you. In other words, if you’ve typed in a constructor with arguments, you won’t have a no-arg constructor unless you type it in yourself!
• Every constructor has, as its first statement, either a call to an overloaded constructor “this()” or a call to the superclass constructor “super()”. (You cant do both in the same constructor)
• If you do type in a constructor, and you do not type in the call to super() or a call to this(), the compiler will insert a no-arg call to super() for you, as the very first statement in the constructor.
• A call to super() can be either a no-arg call or can include arguments passed to the super constructor. (The compiler will not insert the super with arguments call by itself. You have to do it manually)
• A no-arg constructor is not necessarily the default (i.e., compiler-supplied) constructor, although the default constructor is always a no-arg constructor. The default constructor is the one the compiler provides! While the default constructor is always a no-arg constructor, you’re free to put in your own no-arg constructor.
• You cannot make a call to an instance method, or access an instance variable, until after the super constructor runs.
• Only static variables and methods can be accessed as part of the call to super() or this(). (Example: super(Car.NAME) is OK, because NAME is declared as a static variable.)
• Abstract classes have constructors, and those constructors are always called when a concrete subclass is instantiated.
• Interfaces do not have constructors. Interfaces are not part of an object’s inheritance tree.
• The only way a constructor can be invoked is from within another constructor. In other words, you can’t write code that actually calls a constructor explicitly as follows:
class Lamborghini {
Lamborghini() { } // constructor
void doStuff() {
Lamborghini(); // calling the constructor - illegal!
}
}
Determine Whether a Default Constructor Will Be Created
The following example shows a Lamborghini class with two constructors:
class Lamborghini {
Lamborghini() { }
Lamborghini(String name) { }
}
Will the compiler put in a default constructor for the class above? “No!” What about for the following variation of the class?
class Lamborghini {
Lamborghini(String name) { }
}
Now will the compiler insert a default constructor? “No Again!” What about this class?
class Lamborghini { }
Now we’re talking. The compiler will generate a default constructor for the preceding class, because the class doesn’t have any constructors defined. OK, what about this one below?
class Lamborghini {
void Lamborghini() { }
}
You might be tempted to say that, the compiler won’t create one, since there already is a constructor in the Lamborghini class? Take another look at the Lamborghini class.
What’s wrong with the Lamborghini() constructor? It isn’t a constructor at all! It’s simply a method that happens to have the same name as the class. Remember, the return type is a dead straight way to tell us that we’re looking at a method, and not a constructor. So, here again the compiler will put the default no-arg constructor in the class.
Some Questions:
Q: How do you know for sure whether a default constructor will be created?
A: Because you didn’t write any constructors in your class.
Q: How do you know what the default constructor will look like?
A: Because...
• The default constructor has the same access modifier as the class.
• The default constructor has no arguments.
• The default constructor includes a no-arg call to the super constructor (super()).
What happens if the super constructor has arguments?
Constructors can have arguments just as methods can, and if you try to invoke a method that takes, say, an int, but you don’t pass anything to the method, the compiler will complain.
So if your super constructor (that is, the constructor of your immediate superclass/parent) has arguments, you must type in the call to super(), supplying the appropriate arguments. Crucial point: if your superclass does not have a no-arg constructor, you must type a constructor in your class (the subclass) because you need a place to put in the call to super with the appropriate arguments.
The following is an example of the problem:
class Car {
Car(String name) { }
}
class Lamborghini extends Car {
Lamborghini() {
super(); // Problem!
}
}
And once again the compiler treats us with the stunningly lucid:
Lamborghini.java:7: cannot resolve symbol
symbol : constructor Car ()
location: class Car
super(); // Problem!
^
If you’re lucky (and it’s a full moon), your compiler might be a little more explicit. But again, the problem is that there just isn’t a match for what we’re trying to invoke with super()—an Car constructor with no arguments.
Another way to put this is that if your superclass does not have a no-arg constructor, then in your subclass you will not be able to use the default constructor supplied by the compiler. It’s that simple. Because the compiler can only put in a call to a no-arg super(), you won’t even be able to compile something like this:
class Dress {
Dress(String s) { }
}
class Skirt extends Dress { }
Trying to compile this code gives us exactly the same error we got when we put a constructor in the subclass with a call to the no-arg version of super():
Dress.java:4: cannot resolve symbol
symbol : constructor Dress ()
location: class Dress
class Skirt extends Dress { }
^
In fact, the preceding Dress and Skirt code is implicitly the same as the following code, where we’ve supplied a constructor for Skirt that’s identical to the default constructor supplied by the compiler:
class Dress {
Dress(String s) { }
}
class Skirt extends Dress {
// Constructor identical to compiler-supplied
// default constructor
Skirt() {
super(); // Won't work!
} // Invokes a no-arg Dress() constructor,
} // but there isn't one!
One last point on the whole default constructor thing, constructors are never inherited. They aren’t methods. They can’t be overridden (because they aren’t methods and only instance methods can be overridden). So the type of constructor(s) your superclass has in no way determines the type of default constructor you’ll get. Some folks mistakenly believe that the default constructor somehow matches the super constructor, either by the arguments the default constructor will have (remember, the default constructor is always a no-arg), or by the arguments used in the compiler-supplied call to super().
So, although constructors can’t be overridden, you’ve already seen that they can be overloaded, and typically are.
Overloaded Constructors
Overloading a constructor means typing in multiple versions of the constructor, each having a different argument list, like the following examples:
class Car {
Car() { }
Car(String s) { }
}
The preceding Car class has two overloaded constructors, one that takes a string, and one with no arguments. Because there’s no code in the no-arg version, it’s actually identical to the default constructor the compiler supplies, but remember—since there’s already a constructor in this class (the one that takes a string), the compiler won’t supply a default constructor. If you want a no-arg constructor to overload the with-args version you already have, you’re going to have to type it yourself, just as in the Car example.
Overloading a constructor is typically used to provide alternate ways for clients to instantiate objects of your class. For example, if a client knows the Car name, they can pass that to a Car constructor that takes a string. But if they don’t know the name, the client can call the no-arg constructor and that constructor can supply a default name. Here’s what it looks like:
1. public class Car {
2. String name;
3. Car(String name) {
4. this.name = name;
5. }
6.
7. Car() {
8. this(makeRandomName());
9. }
10.
11. static String makeRandomName() {
12. int x = (int) (Math.random() * 5);
13. String name = new String[] {"Ferrari", "Lamborghini",
"Rover", "Spyker",
"Lotus"}[x];
14. return name;
15. }
16.
17. public static void main (String [] args) {
18. Car a = new Car();
19. System.out.println(a.name);
20. Car b = new Car("Proton");
21. System.out.println(b.name);
22. }
23. }
Running the code four times produces this output:
% java Car
Lotus
Proton
% java Car
Ferrari
Proton
% java Car
Rover
Proton
% java Car
Ferrari
Proton
There’s a lot going on in the preceding code. Figure 2-7 shows the call stack for constructor invocations when a constructor is overloaded. Take a look at the call stack, and then let’s walk through the code straight from the top.
• Line 2 Declare a String instance variable name.
• Lines 3–5 Constructor that takes a String, and assigns it to instance variable name.
• Line 7. Assume every Car needs a name, but the client (calling code) might not always know what the name should be, so you’ll assign a random name. The no-arg constructor generates a name by invoking the makeRandomName() method.
• Line 8 The no-arg constructor invokes its own overloaded constructor that takes a String, in effect calling it the same way it would be called if client code were doing a new to instantiate an object, passing it a String for the name. The overloaded invocation uses the keyword this, but uses it as though it were a method name, this(). So line 8 is simply calling the constructor on line 3, passing it a randomly selected String rather than a client-code chosen name.
• Line 11 Notice that the makeRandomName() method is marked static! That’s because you cannot invoke an instance (in other words, nonstatic) method (or access an instance variable) until after the super constructor has run. And since the super constructor will be invoked from the constructor on line 3, rather than from the one on line 7, line 8 can use only a static method to generate the name. If we wanted all Cars not specifically named by the caller to have the same default name, say, “Ford,” then line 8 could have read this("Ford"); rather than calling a method that returns a string with the randomly chosen name.
• Line 12 This doesn’t have anything to do with constructors, but since we’re all here to learn...it generates a random integer between 0 and 4.
• Line 13 We’re creating a new String object (just a single String instance), but we want the string to be selected randomly from a list. Except we don’t have the list, so we need to make it. So in that one line of code we
1. Declare a String variable, name.
2. Create a String array (anonymously—we don’t assign the array itself to anything).
3. Retrieve the string at index [x] (x being the random number generated on line 12) of the newly created String array.
4. Assign the string retrieved from the array to the declared instance variable name. We could have made it much easier to read if we’d just written
5. String[] nameList = {"Ferrari", "Lamborghini", "Rover", "Spyker","Lotus"};
6. String name = nameList[x];
• Line 18 We’re invoking the no-arg version of the constructor (causing a random name from the list to be passed to the other constructor).
• Line 20 We’re invoking the overloaded constructor that takes a string representing the name.
The key point to get from this code example is in line 8. Rather than calling super(), we’re calling this(), and this() always means a call to another constructor in the same class. OK, fine, but what happens after the call to this()? Sooner or later the super() constructor gets called, right? Yes indeed. A call to this() just means you’re delaying the inevitable. Some constructor, somewhere, must make the call to super().
Key Rule: The first line in a constructor must be a call to super() or a call to this().
No exceptions. If you have neither of those calls in your constructor, the compiler will insert the no-arg call to super(). In other words, if constructor A() has a call to this(), the compiler knows that constructor A() will not be the one to invoke super().
The preceding rule means a constructor can never have both a call to super() and a call to this(). Because each of those calls must be the first statement in a constructor, you can’t legally use both in the same constructor. That also means the compiler will not put a call to super() in any constructor that has a call to this().
Thought question: What do you think will happen if you try to compile the following code?
class A {
A() {
this("Car");
}
A(String s) {
this();
}
}
Your compiler may not actually catch the problem (it varies depending on your compiler, but most won’t catch the problem). It assumes you know what you’re doing. Can you spot the flaw? Given that a super constructor must always be called, where would the call to super() go? Remember, the compiler won’t put in a default constructor if you’ve already got one or more constructors in your class. And when the compiler doesn’t put in a default constructor, it still inserts a call to super() in any constructor that doesn’t explicitly have a call to the super constructor—unless, that is, the constructor already has a call to this(). So in the preceding code, where can super() go? The only two constructors in the class both have calls to this(), and in fact you’ll get exactly what you’d get if you typed the following method code:
public void go() {
doStuff();
}
public void doStuff() {
go();
}
Now can you see the problem? Of course you can. The stack explodes! Two overloaded constructors both calling this() are two constructors calling each other. Over and over and over, resulting in
% java A
Exception in thread "main" java.lang.StackOverflowError
The benefit of having overloaded constructors is that you offer flexible ways to instantiate objects from your class. The benefit of having one constructor invoke another overloaded constructor is to avoid code duplication. In the Car example, there wasn’t any code other than setting the name, but imagine if after line 4 there was still more work to be done in the constructor. By putting all the other constructor work in just one constructor, and then having the other constructors invoke it, you don’t have to write and maintain multiple versions of that other important constructor code. Basically, each of the other not-the-real-one overloaded constructors will call another overloaded constructor, passing it whatever data it needs (data the client code didn’t supply).
Constructors and instantiation become even more exciting (just when you thought this chapter is going to end), when you get to inner classes, but I know you can stand to have only so much fun in one chapter, so I am holding the rest of the discussion on instantiating inner classes until a later point in time (A Future Chapter)
Previous Chapter: Chapter 11 - Legal Return Types
Next Chapter: Chapter 13 - Statics
We already have a lot to discuss here. So let’s get started.
Constructor Basics
Every class, including abstract classes, MUST have a constructor. Hard Code that into your brain. But just because a class must have one, doesn’t mean the programmer has to type it. A constructor looks like this:
class Car {
Car() { } // The constructor for the Car class
}
You notice anything missing in the declaration above? There’s no return type! Two key points to remember about constructors are that they have no return type and their names must exactly match the class name. Typically, constructors are used to initialize instance variable state, as follows:
class Car {
int size;
String name;
Car(String name, int size) {
this.name = name;
this.size = size;
}
}
In the preceding code example, the Car class does not have a no-arg constructor. That means the following will fail to compile:
Car f = new Car(); // Won't compile, no matching constructor
but the following will compile:
Car f = new Car("Ford", 43); // No problem. Arguments match
// the Car constructor.
So it’s very common for a class to have a no-arg constructor, regardless of how many other overloaded constructors are in the class (constructors can be overloaded just like methods). You can’t always make that work for your classes; occasionally you have a class where it makes no sense to create an instance without supplying information to the constructor. A java.awt.Color object, for example, can’t be created by calling a no-arg constructor, because that would be like saying to the JVM, “Make me a new Color object, and I really don’t care what color it is....” Do you seriously want the JVM making your color choices?
Constructor Chaining
We know that constructors are invoked at runtime when you say new on some class type as follows:
Lamborghini h = new Lamborghini();
But what really happens when you say new Lamborghini() ? (Assume Lamborghini extends Car and Car extends Object.)
1. Lamborghini constructor is invoked. Every constructor invokes the constructor of its superclass with an (implicit) call to super(),
2. Car constructor is invoked (Car is the superclass of Lamborghini).
3. Object constructor is invoked (Object is the ultimate superclass of all classes, so class Car extends Object even though you don’t actually type “extends Object” into the Car class declaration. It’s implicit.) At this point we’re on the top of the hierarchy.
4. Object instance variables are given their explicit values. By explicit values, we mean values that are assigned at the time the variables are declared, like “int x = 27”, where “27” is the explicit value (as opposed to the default value) of the instance variable.
5. Object constructor completes.
6. Car instance variables are given their explicit values (if any).
7. Car constructor completes.
8. Lamborghini instance variables are given their explicit values (if any).
9. Lamborghini constructor completes.
Rules for Constructors
The following list summarizes the rules you’ll need to know about Constructors. There are very important and you MUST remember these to answer the questions related to Constructors in the SCJP Exam.
• Constructors can use any access modifier, including private. (We will deal with private constructors in one of the later chapters)
• The constructor name must match the name of the class. (100% Case Sensitive)
• Constructors must not have a return type.
• It’s legal (but probably stupid) to have a method with the same name as the class, but that doesn’t make it a constructor. If you see a return type, it’s a method and not a constructor. In fact, you could have both a method and a constructor with the same name—the name of the class—in the same class, and that’s not a problem for Java. Be careful not to mistake a method for a constructor—be sure to look for a return type.
• If you don’t type a constructor into your class code, a default constructor will be automatically generated by the compiler.
• The default constructor is ALWAYS a no-arg constructor. (Obviously the compiler has no clue what all arguments you might want for your class. So it takes the safe way out with a no argument constructor)
• If you want a no-arg constructor and you’ve typed any other constructor(s) into your class code, the compiler won’t provide the no-arg constructor (or any other constructor) for you. In other words, if you’ve typed in a constructor with arguments, you won’t have a no-arg constructor unless you type it in yourself!
• Every constructor has, as its first statement, either a call to an overloaded constructor “this()” or a call to the superclass constructor “super()”. (You cant do both in the same constructor)
• If you do type in a constructor, and you do not type in the call to super() or a call to this(), the compiler will insert a no-arg call to super() for you, as the very first statement in the constructor.
• A call to super() can be either a no-arg call or can include arguments passed to the super constructor. (The compiler will not insert the super with arguments call by itself. You have to do it manually)
• A no-arg constructor is not necessarily the default (i.e., compiler-supplied) constructor, although the default constructor is always a no-arg constructor. The default constructor is the one the compiler provides! While the default constructor is always a no-arg constructor, you’re free to put in your own no-arg constructor.
• You cannot make a call to an instance method, or access an instance variable, until after the super constructor runs.
• Only static variables and methods can be accessed as part of the call to super() or this(). (Example: super(Car.NAME) is OK, because NAME is declared as a static variable.)
• Abstract classes have constructors, and those constructors are always called when a concrete subclass is instantiated.
• Interfaces do not have constructors. Interfaces are not part of an object’s inheritance tree.
• The only way a constructor can be invoked is from within another constructor. In other words, you can’t write code that actually calls a constructor explicitly as follows:
class Lamborghini {
Lamborghini() { } // constructor
void doStuff() {
Lamborghini(); // calling the constructor - illegal!
}
}
Determine Whether a Default Constructor Will Be Created
The following example shows a Lamborghini class with two constructors:
class Lamborghini {
Lamborghini() { }
Lamborghini(String name) { }
}
Will the compiler put in a default constructor for the class above? “No!” What about for the following variation of the class?
class Lamborghini {
Lamborghini(String name) { }
}
Now will the compiler insert a default constructor? “No Again!” What about this class?
class Lamborghini { }
Now we’re talking. The compiler will generate a default constructor for the preceding class, because the class doesn’t have any constructors defined. OK, what about this one below?
class Lamborghini {
void Lamborghini() { }
}
You might be tempted to say that, the compiler won’t create one, since there already is a constructor in the Lamborghini class? Take another look at the Lamborghini class.
What’s wrong with the Lamborghini() constructor? It isn’t a constructor at all! It’s simply a method that happens to have the same name as the class. Remember, the return type is a dead straight way to tell us that we’re looking at a method, and not a constructor. So, here again the compiler will put the default no-arg constructor in the class.
Some Questions:
Q: How do you know for sure whether a default constructor will be created?
A: Because you didn’t write any constructors in your class.
Q: How do you know what the default constructor will look like?
A: Because...
• The default constructor has the same access modifier as the class.
• The default constructor has no arguments.
• The default constructor includes a no-arg call to the super constructor (super()).
What happens if the super constructor has arguments?
Constructors can have arguments just as methods can, and if you try to invoke a method that takes, say, an int, but you don’t pass anything to the method, the compiler will complain.
So if your super constructor (that is, the constructor of your immediate superclass/parent) has arguments, you must type in the call to super(), supplying the appropriate arguments. Crucial point: if your superclass does not have a no-arg constructor, you must type a constructor in your class (the subclass) because you need a place to put in the call to super with the appropriate arguments.
The following is an example of the problem:
class Car {
Car(String name) { }
}
class Lamborghini extends Car {
Lamborghini() {
super(); // Problem!
}
}
And once again the compiler treats us with the stunningly lucid:
Lamborghini.java:7: cannot resolve symbol
symbol : constructor Car ()
location: class Car
super(); // Problem!
^
If you’re lucky (and it’s a full moon), your compiler might be a little more explicit. But again, the problem is that there just isn’t a match for what we’re trying to invoke with super()—an Car constructor with no arguments.
Another way to put this is that if your superclass does not have a no-arg constructor, then in your subclass you will not be able to use the default constructor supplied by the compiler. It’s that simple. Because the compiler can only put in a call to a no-arg super(), you won’t even be able to compile something like this:
class Dress {
Dress(String s) { }
}
class Skirt extends Dress { }
Trying to compile this code gives us exactly the same error we got when we put a constructor in the subclass with a call to the no-arg version of super():
Dress.java:4: cannot resolve symbol
symbol : constructor Dress ()
location: class Dress
class Skirt extends Dress { }
^
In fact, the preceding Dress and Skirt code is implicitly the same as the following code, where we’ve supplied a constructor for Skirt that’s identical to the default constructor supplied by the compiler:
class Dress {
Dress(String s) { }
}
class Skirt extends Dress {
// Constructor identical to compiler-supplied
// default constructor
Skirt() {
super(); // Won't work!
} // Invokes a no-arg Dress() constructor,
} // but there isn't one!
One last point on the whole default constructor thing, constructors are never inherited. They aren’t methods. They can’t be overridden (because they aren’t methods and only instance methods can be overridden). So the type of constructor(s) your superclass has in no way determines the type of default constructor you’ll get. Some folks mistakenly believe that the default constructor somehow matches the super constructor, either by the arguments the default constructor will have (remember, the default constructor is always a no-arg), or by the arguments used in the compiler-supplied call to super().
So, although constructors can’t be overridden, you’ve already seen that they can be overloaded, and typically are.
Overloaded Constructors
Overloading a constructor means typing in multiple versions of the constructor, each having a different argument list, like the following examples:
class Car {
Car() { }
Car(String s) { }
}
The preceding Car class has two overloaded constructors, one that takes a string, and one with no arguments. Because there’s no code in the no-arg version, it’s actually identical to the default constructor the compiler supplies, but remember—since there’s already a constructor in this class (the one that takes a string), the compiler won’t supply a default constructor. If you want a no-arg constructor to overload the with-args version you already have, you’re going to have to type it yourself, just as in the Car example.
Overloading a constructor is typically used to provide alternate ways for clients to instantiate objects of your class. For example, if a client knows the Car name, they can pass that to a Car constructor that takes a string. But if they don’t know the name, the client can call the no-arg constructor and that constructor can supply a default name. Here’s what it looks like:
1. public class Car {
2. String name;
3. Car(String name) {
4. this.name = name;
5. }
6.
7. Car() {
8. this(makeRandomName());
9. }
10.
11. static String makeRandomName() {
12. int x = (int) (Math.random() * 5);
13. String name = new String[] {"Ferrari", "Lamborghini",
"Rover", "Spyker",
"Lotus"}[x];
14. return name;
15. }
16.
17. public static void main (String [] args) {
18. Car a = new Car();
19. System.out.println(a.name);
20. Car b = new Car("Proton");
21. System.out.println(b.name);
22. }
23. }
Running the code four times produces this output:
% java Car
Lotus
Proton
% java Car
Ferrari
Proton
% java Car
Rover
Proton
% java Car
Ferrari
Proton
There’s a lot going on in the preceding code. Figure 2-7 shows the call stack for constructor invocations when a constructor is overloaded. Take a look at the call stack, and then let’s walk through the code straight from the top.
• Line 2 Declare a String instance variable name.
• Lines 3–5 Constructor that takes a String, and assigns it to instance variable name.
• Line 7. Assume every Car needs a name, but the client (calling code) might not always know what the name should be, so you’ll assign a random name. The no-arg constructor generates a name by invoking the makeRandomName() method.
• Line 8 The no-arg constructor invokes its own overloaded constructor that takes a String, in effect calling it the same way it would be called if client code were doing a new to instantiate an object, passing it a String for the name. The overloaded invocation uses the keyword this, but uses it as though it were a method name, this(). So line 8 is simply calling the constructor on line 3, passing it a randomly selected String rather than a client-code chosen name.
• Line 11 Notice that the makeRandomName() method is marked static! That’s because you cannot invoke an instance (in other words, nonstatic) method (or access an instance variable) until after the super constructor has run. And since the super constructor will be invoked from the constructor on line 3, rather than from the one on line 7, line 8 can use only a static method to generate the name. If we wanted all Cars not specifically named by the caller to have the same default name, say, “Ford,” then line 8 could have read this("Ford"); rather than calling a method that returns a string with the randomly chosen name.
• Line 12 This doesn’t have anything to do with constructors, but since we’re all here to learn...it generates a random integer between 0 and 4.
• Line 13 We’re creating a new String object (just a single String instance), but we want the string to be selected randomly from a list. Except we don’t have the list, so we need to make it. So in that one line of code we
1. Declare a String variable, name.
2. Create a String array (anonymously—we don’t assign the array itself to anything).
3. Retrieve the string at index [x] (x being the random number generated on line 12) of the newly created String array.
4. Assign the string retrieved from the array to the declared instance variable name. We could have made it much easier to read if we’d just written
5. String[] nameList = {"Ferrari", "Lamborghini", "Rover", "Spyker","Lotus"};
6. String name = nameList[x];
• Line 18 We’re invoking the no-arg version of the constructor (causing a random name from the list to be passed to the other constructor).
• Line 20 We’re invoking the overloaded constructor that takes a string representing the name.
The key point to get from this code example is in line 8. Rather than calling super(), we’re calling this(), and this() always means a call to another constructor in the same class. OK, fine, but what happens after the call to this()? Sooner or later the super() constructor gets called, right? Yes indeed. A call to this() just means you’re delaying the inevitable. Some constructor, somewhere, must make the call to super().
Key Rule: The first line in a constructor must be a call to super() or a call to this().
No exceptions. If you have neither of those calls in your constructor, the compiler will insert the no-arg call to super(). In other words, if constructor A() has a call to this(), the compiler knows that constructor A() will not be the one to invoke super().
The preceding rule means a constructor can never have both a call to super() and a call to this(). Because each of those calls must be the first statement in a constructor, you can’t legally use both in the same constructor. That also means the compiler will not put a call to super() in any constructor that has a call to this().
Thought question: What do you think will happen if you try to compile the following code?
class A {
A() {
this("Car");
}
A(String s) {
this();
}
}
Your compiler may not actually catch the problem (it varies depending on your compiler, but most won’t catch the problem). It assumes you know what you’re doing. Can you spot the flaw? Given that a super constructor must always be called, where would the call to super() go? Remember, the compiler won’t put in a default constructor if you’ve already got one or more constructors in your class. And when the compiler doesn’t put in a default constructor, it still inserts a call to super() in any constructor that doesn’t explicitly have a call to the super constructor—unless, that is, the constructor already has a call to this(). So in the preceding code, where can super() go? The only two constructors in the class both have calls to this(), and in fact you’ll get exactly what you’d get if you typed the following method code:
public void go() {
doStuff();
}
public void doStuff() {
go();
}
Now can you see the problem? Of course you can. The stack explodes! Two overloaded constructors both calling this() are two constructors calling each other. Over and over and over, resulting in
% java A
Exception in thread "main" java.lang.StackOverflowError
The benefit of having overloaded constructors is that you offer flexible ways to instantiate objects from your class. The benefit of having one constructor invoke another overloaded constructor is to avoid code duplication. In the Car example, there wasn’t any code other than setting the name, but imagine if after line 4 there was still more work to be done in the constructor. By putting all the other constructor work in just one constructor, and then having the other constructors invoke it, you don’t have to write and maintain multiple versions of that other important constructor code. Basically, each of the other not-the-real-one overloaded constructors will call another overloaded constructor, passing it whatever data it needs (data the client code didn’t supply).
Constructors and instantiation become even more exciting (just when you thought this chapter is going to end), when you get to inner classes, but I know you can stand to have only so much fun in one chapter, so I am holding the rest of the discussion on instantiating inner classes until a later point in time (A Future Chapter)
Previous Chapter: Chapter 11 - Legal Return Types
Next Chapter: Chapter 13 - Statics
Labels:
constructor creation,
constructor overloading,
constructors in java,
Java,
java constructors,
overloading constructors
| Reactions: |
Chapter 11: Legal Return Types
In the previous chapters we have seen many methods and classes. Every method in java has a return type which specifies the kind of data that would be returned by the current method. It is mandatory for all java methods to return something and if it is not going to return anything, we have to mark the method with a “void” return type to let the JVM know that it must not expect anything from the method. The purpose of this article is to take a look at what you can declare as a return type and as values. We will also cover a few other nuances of returning data with respect to other scenarios that we had covered in the previous chapters.
Return Type Declarations
This section looks at what you’re allowed to declare as a return type, which depends primarily on whether you are overriding, overloading, or declaring a new method.
Return Types on Overloaded Methods
Remember that method overloading is nothing more than name reuse. The overloaded method is a completely different method from any other method of the same name in the current class. So if you inherit a method but overload it in a subclass, you’re not subject to the restrictions of overriding. This essentially means that you can declare any return type you want. What you can’t do is change only the return type. To overload a method, remember, you must change the arDriveent list. The following code shows an overloaded method:
public class Car{
void go() { }
}
public class Ferrari extends Car {
String go(int x) {
return null;
}
}
Notice that the Ferrari version of the method uses a different return type. That’s perfectly fine. As long as you’ve changed the arDriveent list, you’re overloading the method, so the return type doesn’t have to match that of the superclass version. What you’re NOT allowed to do is this:
public class Car{
void go() { }
}
public class Ferrari extends Car {
String go() { //Illegal! Can't change only the return type
return null;
}
}
Overriding and Return Types, and Covariant Returns
When a subclass wants to change the implementation of an inherited method (override), the subclass must define a method that matches the inherited version exactly. Or, as of Java 5, you’re allowed to change the return type in the overriding method as long as the new return type is a subtype of the declared return type of the super-class method. (This is called Co-variant Returns)
Let’s look at a covariant return in action:
class Car {
Car drive(char c) {
return new Car();
}
}
class Lamborghini extends Car {
Lamborghini drive(char c) { // legal override as of Java 1.5
return new Lamborghini();
}
}
As of Java 5, this code will compile. If you were to attempt to compile this code with a 1.4 compiler or with the source flag as follows:
javac -source 1.4 Lamborghini.java
You would get a compiler error something that would look simething like this:
attempting to use incompatible return type
There are many other rules that apply to overriding, including those for access modifiers and declared exceptions, but those rules aren’t relevant to the return type discussion and we have already seen them in the chapter where we discussed about Overriding.
For the exam, be sure to remember that overloaded methods can change the return type, but overriding methods can do so only within the bounds of covariant returns.
Returning a Value
There are 6 golden rules for returning values from a method. Be sure to remember these clearly:
1. You can return NULL in a method that has an Object as return type
public Button drive() {
return null;
}
2. An Array is a perfectly legal return type
public String[] go() {
return new String[] {"Anand", "Rocky", "Austin"};
}
3. In a method with a primitive return type, you can return any value or variable that can be implicitly converted to the declared return type.
public int Car() {
char c = 'c';
return c; // char is compatible with int
}
4. In a method with a primitive return type, you can return any value or variable that can be explicitly cast to the declared return type.
public int Car () {
float f = 32.5f;
return (int) f;
}
5. You must not return anything from a method with a void return type.
public void Ferrari() {
return "this is it"; // You cant do this. Code wont compile
}
6. In a method with an object reference return type, you can return any object type that can be implicitly cast to the declared return type.
public Car getCar() {
return new BMW(); // Assume BMW extends Car
}
public Object getObject() {
int[] nums = {1,2,3};
return nums; // Return an int array,
// which is still an object
}
public interface Drivable { }
public class Drive implements Drivable { }
public class TestDrivable {
// Method with an interface return type
public Drivable getDrivable() {
return new Drive(); // Return interface implementer
}
}
Exam Tip:
Previous Chapter: Chapter 10 - Implementing an Interface
Next Chapter: Chapter 12 - Constructors and Instantiation
Return Type Declarations
This section looks at what you’re allowed to declare as a return type, which depends primarily on whether you are overriding, overloading, or declaring a new method.
Return Types on Overloaded Methods
Remember that method overloading is nothing more than name reuse. The overloaded method is a completely different method from any other method of the same name in the current class. So if you inherit a method but overload it in a subclass, you’re not subject to the restrictions of overriding. This essentially means that you can declare any return type you want. What you can’t do is change only the return type. To overload a method, remember, you must change the arDriveent list. The following code shows an overloaded method:
public class Car{
void go() { }
}
public class Ferrari extends Car {
String go(int x) {
return null;
}
}
Notice that the Ferrari version of the method uses a different return type. That’s perfectly fine. As long as you’ve changed the arDriveent list, you’re overloading the method, so the return type doesn’t have to match that of the superclass version. What you’re NOT allowed to do is this:
public class Car{
void go() { }
}
public class Ferrari extends Car {
String go() { //Illegal! Can't change only the return type
return null;
}
}
Overriding and Return Types, and Covariant Returns
When a subclass wants to change the implementation of an inherited method (override), the subclass must define a method that matches the inherited version exactly. Or, as of Java 5, you’re allowed to change the return type in the overriding method as long as the new return type is a subtype of the declared return type of the super-class method. (This is called Co-variant Returns)
Let’s look at a covariant return in action:
class Car {
Car drive(char c) {
return new Car();
}
}
class Lamborghini extends Car {
Lamborghini drive(char c) { // legal override as of Java 1.5
return new Lamborghini();
}
}
As of Java 5, this code will compile. If you were to attempt to compile this code with a 1.4 compiler or with the source flag as follows:
javac -source 1.4 Lamborghini.java
You would get a compiler error something that would look simething like this:
attempting to use incompatible return type
There are many other rules that apply to overriding, including those for access modifiers and declared exceptions, but those rules aren’t relevant to the return type discussion and we have already seen them in the chapter where we discussed about Overriding.
For the exam, be sure to remember that overloaded methods can change the return type, but overriding methods can do so only within the bounds of covariant returns.
Returning a Value
There are 6 golden rules for returning values from a method. Be sure to remember these clearly:
1. You can return NULL in a method that has an Object as return type
public Button drive() {
return null;
}
2. An Array is a perfectly legal return type
public String[] go() {
return new String[] {"Anand", "Rocky", "Austin"};
}
3. In a method with a primitive return type, you can return any value or variable that can be implicitly converted to the declared return type.
public int Car() {
char c = 'c';
return c; // char is compatible with int
}
4. In a method with a primitive return type, you can return any value or variable that can be explicitly cast to the declared return type.
public int Car () {
float f = 32.5f;
return (int) f;
}
5. You must not return anything from a method with a void return type.
public void Ferrari() {
return "this is it"; // You cant do this. Code wont compile
}
6. In a method with an object reference return type, you can return any object type that can be implicitly cast to the declared return type.
public Car getCar() {
return new BMW(); // Assume BMW extends Car
}
public Object getObject() {
int[] nums = {1,2,3};
return nums; // Return an int array,
// which is still an object
}
public interface Drivable { }
public class Drive implements Drivable { }
public class TestDrivable {
// Method with an interface return type
public Drivable getDrivable() {
return new Drive(); // Return interface implementer
}
}
Exam Tip:
Watch for methods that declare an abstract class or interface return type, and know that any object that passes the IS-A test (in other words, would test true using the instanceof operator) can be returned from that method—for example:
public abstract class Car { }
public class Lexus extends Car { }
public class Test {
public Car go() {
return new Lexus(); // OK, Lexus "is-a" Car
}
}
This code will compile, the return value is a subtype.
Previous Chapter: Chapter 10 - Implementing an Interface
Next Chapter: Chapter 12 - Constructors and Instantiation
| Reactions: |
Monday, January 3, 2011
Quick Recap – Chapters 1 to 5
We have successfully completed 5 chapters in our preparation towards the SCJP certification preparation. Let us do a quick recap to cover what we have seen so far.
Chapter 1:
We saw that classes are the backbone based on which the java programming language revolves and everything in java is an Object (Java is an object oriented language)
• A class is like a template that describes the kinds of state and behavior that a particular object will support
• A class contains variables that refer to the objects state and methods that describe the behavior a class is expected to portray
• Java programs run on the Java Virtual Machine (JVM)
• Keywords are predefined words in the java language that tell the JVM to perform a predefined action
• You cannot use keywords are names for your variables or methods
Chapter 2:
We covered the declaration of various java entities like classes, interfaces etc in this chapter.
Java Source Files
• There can be only one public class per source file (a .java extension file)
• If there is a public class in a file, then the file name should be the name of the public class with a .java extension
• The package statement should always be the first statement in a java source file
• A file can have more than one non-public class
Class & Interface Declaration:
• A class can be created by using the “class” keyword
• The different types of classes we can create are final, abstract and the normal java classes
• An abstract class is a special kind of class that cannot be instantiated
• Any class that has one or more abstract methods has to be declared abstract
• An Interface defines a contract of what a class can do without saying anything about the exact implementation
• Any class that implements an interface has to provide implementation (code) for all the methods in the interface
• An interface is an 100% abstract class
• Variables in an interface are by default static and final which means they are constants
• An interface or an abstract cannot have final methods
• Every class has atleast one constructor that would get invoked during the process of object creation of the class
• If you don’t write a constructor, the compiler will build a default no-arg constructor for you
• Constructors cannot be abstract, static or final
Declaring Variables:
• There are two types of variables in Java – Primitives and Reference variables
• Static variables belong to the class and not to any object instance
• Variables declared inside methods are called local variables whereas ones declared inside a class (outside of any methods) are called instance variables
• Arrays are objects that hold multiple variables of the same type
• Though arrays are useful, collections like ArrayList or Vector provide more functionality than normal arrays
JavaBean Naming Conventions:
This is something I should have covered in the Declarations chapter. Since it is very small I thought I will add it to the quick re-cap chapter.
• All class names should start with a Capital letter and should follow camel case. Ex: TestStaticClass (See the capitalization of subsequent words)
• All method names should start with a small letter and should follow camel case. Ex: getNameOfEmployee()
• Method names should contain a prefix that gives an indication of what the method is supposed to do
• “get” is used usually for methods that return a particular value like getName() or getAge() etc
• “set” or “put” is used usually for methods that are used to modify the value like setName() or putDepositMoney() etc
• Methods that check a Boolean value must be prefixed with “is” like isTrue() or isValid() etc
• “add” is a keyword that is used usually with adding listeners to UI components like addEventListener() etc
Chapter 3:
In this chapter we had a detailed look at enumerations.
• enums can be used to refer to pre-defined values (constants) for your java program
• It is a good practice to have your enums in all CAPS to let other programmers know that they are constants
• enums cannot be declared inside methods
• Every enum has a static method, values(), that returns an array of the enum’s values in the order they’re declared
Chapter 4:
In this chapter we looked at the various Access Modifiers in java. They are public, private, protected and the default (no keyword) access modifiers.
• public is the least restrictive modifier whereas private is the most restrictive
• Though you may feel that public is better because all other classes can access your methods, that is seldom the case because a code that is visible to all other classes is not secure and that is not the best way to write your code. It is always best to provide just the appropriate level of access to methods and variables instead of having all of them public
• Protected and default access behave the same way as long as inheritance is not involved
• You cannot apply access modifiers to local variables
Chapter 5:
In this chapter we looked at the Non-Access Modifiers, the modifiers that do not alter the accessibility of java class members but that do alter its behavior.
• strictfp ensures that the floating point calculations in your code is in accordance to the IEEE 754 guidelines
• final classes cannot be inherited (sub-classed or extended)
• All java’s core library classes (ex: java.lang.String) are final
• An abstract class can never be instantiated
• A class cannot be both abstract and final
• Final methods cannot be overridden by any sub-class that might extend the original class
• Abstract methods have to be implemented (overridden) by the sub-class that extends the original class
• A method cannot be both abstract and final
• A synchronized method can be executed by only one thread at any time
• A native method is one which is implemented in a language that is not java (usually C)
• Static methods belong to a class and not any object instance of a class
• Static methods can call/invoke only other static methods/variables
• Final variables cannot be modified once they are assigned an initial value (not the default value)
• Transient variables will not be serialized when the object is serialized
• Using volatile keyword for variables in a multi-threaded application is a bad idea
• Static variables belong to a class and no matter how many objects you create of that class, there will be only one instance of the static variable
• Method arguments can be declared final which ensures that those variables will not be modified inside the method code
That rounds up the quick recap of the first 5 chapters of this SCJP series.
Previous Chapter: Chapter 5
Next Chapter: Self Test Chapters 1 to 5
Tip: You can bookmark this page (and the other quick recaps) to refresh just before your exam.
Chapter 1:
We saw that classes are the backbone based on which the java programming language revolves and everything in java is an Object (Java is an object oriented language)
• A class is like a template that describes the kinds of state and behavior that a particular object will support
• A class contains variables that refer to the objects state and methods that describe the behavior a class is expected to portray
• Java programs run on the Java Virtual Machine (JVM)
• Keywords are predefined words in the java language that tell the JVM to perform a predefined action
• You cannot use keywords are names for your variables or methods
Chapter 2:
We covered the declaration of various java entities like classes, interfaces etc in this chapter.
Java Source Files
• There can be only one public class per source file (a .java extension file)
• If there is a public class in a file, then the file name should be the name of the public class with a .java extension
• The package statement should always be the first statement in a java source file
• A file can have more than one non-public class
Class & Interface Declaration:
• A class can be created by using the “class” keyword
• The different types of classes we can create are final, abstract and the normal java classes
• An abstract class is a special kind of class that cannot be instantiated
• Any class that has one or more abstract methods has to be declared abstract
• An Interface defines a contract of what a class can do without saying anything about the exact implementation
• Any class that implements an interface has to provide implementation (code) for all the methods in the interface
• An interface is an 100% abstract class
• Variables in an interface are by default static and final which means they are constants
• An interface or an abstract cannot have final methods
• Every class has atleast one constructor that would get invoked during the process of object creation of the class
• If you don’t write a constructor, the compiler will build a default no-arg constructor for you
• Constructors cannot be abstract, static or final
Declaring Variables:
• There are two types of variables in Java – Primitives and Reference variables
• Static variables belong to the class and not to any object instance
• Variables declared inside methods are called local variables whereas ones declared inside a class (outside of any methods) are called instance variables
• Arrays are objects that hold multiple variables of the same type
• Though arrays are useful, collections like ArrayList or Vector provide more functionality than normal arrays
JavaBean Naming Conventions:
This is something I should have covered in the Declarations chapter. Since it is very small I thought I will add it to the quick re-cap chapter.
• All class names should start with a Capital letter and should follow camel case. Ex: TestStaticClass (See the capitalization of subsequent words)
• All method names should start with a small letter and should follow camel case. Ex: getNameOfEmployee()
• Method names should contain a prefix that gives an indication of what the method is supposed to do
• “get” is used usually for methods that return a particular value like getName() or getAge() etc
• “set” or “put” is used usually for methods that are used to modify the value like setName() or putDepositMoney() etc
• Methods that check a Boolean value must be prefixed with “is” like isTrue() or isValid() etc
• “add” is a keyword that is used usually with adding listeners to UI components like addEventListener() etc
Chapter 3:
In this chapter we had a detailed look at enumerations.
• enums can be used to refer to pre-defined values (constants) for your java program
• It is a good practice to have your enums in all CAPS to let other programmers know that they are constants
• enums cannot be declared inside methods
• Every enum has a static method, values(), that returns an array of the enum’s values in the order they’re declared
Chapter 4:
In this chapter we looked at the various Access Modifiers in java. They are public, private, protected and the default (no keyword) access modifiers.
• public is the least restrictive modifier whereas private is the most restrictive
• Though you may feel that public is better because all other classes can access your methods, that is seldom the case because a code that is visible to all other classes is not secure and that is not the best way to write your code. It is always best to provide just the appropriate level of access to methods and variables instead of having all of them public
• Protected and default access behave the same way as long as inheritance is not involved
• You cannot apply access modifiers to local variables
Chapter 5:
In this chapter we looked at the Non-Access Modifiers, the modifiers that do not alter the accessibility of java class members but that do alter its behavior.
• strictfp ensures that the floating point calculations in your code is in accordance to the IEEE 754 guidelines
• final classes cannot be inherited (sub-classed or extended)
• All java’s core library classes (ex: java.lang.String) are final
• An abstract class can never be instantiated
• A class cannot be both abstract and final
• Final methods cannot be overridden by any sub-class that might extend the original class
• Abstract methods have to be implemented (overridden) by the sub-class that extends the original class
• A method cannot be both abstract and final
• A synchronized method can be executed by only one thread at any time
• A native method is one which is implemented in a language that is not java (usually C)
• Static methods belong to a class and not any object instance of a class
• Static methods can call/invoke only other static methods/variables
• Final variables cannot be modified once they are assigned an initial value (not the default value)
• Transient variables will not be serialized when the object is serialized
• Using volatile keyword for variables in a multi-threaded application is a bad idea
• Static variables belong to a class and no matter how many objects you create of that class, there will be only one instance of the static variable
• Method arguments can be declared final which ensures that those variables will not be modified inside the method code
That rounds up the quick recap of the first 5 chapters of this SCJP series.
Previous Chapter: Chapter 5
Next Chapter: Self Test Chapters 1 to 5
Labels:
chapter review,
Java,
points to remember,
quick recap,
SCJP,
SCJP Certification
| Reactions: |
Sunday, January 2, 2011
Chapter 4: Access Modifiers
Access Modifiers are one of the most important topics when it comes to taking the SCJP exam. You can expect a number of questions from these access modifiers. Some questions test several concepts of access control at the same time, so not knowing one small part of access control could blow an entire question. Let us get started...
An Access Modifier is a key word in java that determines what level of access or visibility a particular java variable/method or class has. There are 4 basic access modifiers in java. They are:
1. Public
2. Protected
3. Default and
4. Private
Private is the most restrictive access modifier whereas public is the least restrictive. Default is the access protection you get when you do not specifically mention an access modifier to be used for a java object.
Java programming does not run by just a single piece of class that has the whole functionality. You have hundreds of classes that interact with one another, passing data between them and returning output to the user of the system. So it is very important for members of one class to access members of another. Here members may refer to variables, methods and even classes. So, this is where the access modifiers come into picture. The modifier associated with every member of the class determines what level of visibility that member has.
Let us say you have a Class A and you are trying to access a method from inside Class B. If the modifier for the method inside class B is restricted (say private) then the compiler will punch you in the face and tell you that what you are doing is wrong. Because, class A is not even supposed to know about the private members of class B and you cant possibly use them.
You need to understand two different access issues:
• Whether method code in one class can access a member of another class
• Whether a subclass can inherit a member of its superclass
The first type of access is when a method in one class tries to access a method or a variable of another class, using the dot operator (.) to invoke a method or retrieve a variable
Ex:
public class Dad {
public String getName() {
return “Vijayakumar”;
}
}
public class Son {
public void findDaddy() {
Dad obj = new Dad();
System.out.println(“The name of Sons Daddy is : “ + obj.getName();
}
}
Do you think the above code will work? Yes it will. That is because both the Dad and Son classes are public and so the Son class can happily access the Dad class and most importantly, the method getName() inside the Dad class is also public which means the Son can happily access that method too.
Let us say the getName() method was private, then the Son wouldn’t be able to access this getName() method and the compiler would have spit out error messages.
Public Members:
If a variable or method is declared public, it means that it can be accessed by anyone or any other class (irrespective of which package they are in). Of course, it is mandatory that the class inside which the public method is placed is visible in the first place for the method or variable to be visible. You can check out the code example in the previous paragraph for an example. The method from Dad class is visible and available for usage inside the son class.
For a subclass, if a member of its superclass is declared public, the subclass inherits that member regardless of whether both classes are in the same package.
Ex:
package pack1;
public class Parent {
public String getName() {
return “Parent”;
}
}
Package pack2;
Import pack1.Parent;
Public class Child extends Parent{
Public String getParentsName() {
return getName();
}
}
If you see the example above, the child class is able to access the parent class’s method getName() even without instantiating an object of the parent because it inherits the Parent class and all its method as part of the inheritance (extends) feature.
Private Members:
Members marked private can’t be accessed by code in any class other than the class in which the private member was declared. Let’s make a small change to the Parent class from an earlier example.
package pack1;
public class Parent {
private String getName() {
return “Parent”;
}
}
Now the getName() method is private and is not visible from within the Child class and the same piece of code would throw up the below compilation error when you try to compile the class.
cannot find symbol
symbol : method getName()
This error method looks as if the method getName() does not exist at all. Of course the method exists but unfortunately it is declared private and hence no class (except the class that has the exact code written into it) can access it. This includes a child class that extends the parent class that has the method.
Note: You can write a method inside the child class that has the same name as the private method in the parent. This does not account as Overriding because the parent class method is not even visible and hence it is just another method and is not considered overriding.
Protected and Default Members:
The protected and default access control levels are almost identical, but with one critical difference. A default member may be accessed only if the class accessing the member belongs to the same package, whereas a protected member can be accessed (through inheritance) by a subclass even if the subclass is in a different package.
Take a look at the following two classes:
package certification;
public class ClassOne {
void testIt() { // No modifier means method has default access
System.out.println("ClassOne");
}
}
In another source code file you have the following:
package otherCertification;
import certification.ClassOne;
class ClassTwo {
static public void main(String[] args) {
ClassOne o = new ClassOne();
o.testIt();
}
}
As you can see, the testIt() method in the first file has default (think: package-level) access. Notice also that class ClassTwo is in a different package from the ClassOne class. When you compile the ClassTwo.java file you will get an error like below:
No method matching testIt() found in class
certification.ClassOne.o.testIt();
From the preceding results, you can see that ClassOne can’t use the ClassTwo's method testIt() because testIt() has default access, and ClassOne is not in the same package as ClassTwo. So ClassOne can’t see it, the compiler complains.
Default and protected behavior differs only when we talk about subclasses. If the protected keyword is used to define a member, any subclass of the class declaring the member can access it through inheritance. It doesn’t matter if the superclass and subclass are in different packages, the protected superclass member is still visible to the subclass. This is in contrast to the default behavior, which doesn’t allow a subclass to access a superclass member unless the subclass is in the same package as the superclass. (See the example above)
Whereas default access doesn’t extend any special consideration to subclasses, the protected modifier respects the parent-child relationship, even when the child class moves away (and joins a new package). So, when you think of default access, think of package restrictions. No exceptions at all. But when you think protected, think package + kids. A class with a protected member is marking that member as having package-level access for all classes, but with a special exception for subclasses outside the package.
Local Variables and Access Modifiers
Can access modifiers be applied to local variables? A BIG NO!
There is never a case where an access modifier can be applied to a local variable, so watch out for code like the following:
class Test {
void doTest() {
private int x = 7; //Not Possible
this.doSomethingElse(x);
}
}
The above code will not compile or run. Dont think that the private keyword is legal inside the method doTest().
You can be certain that any local variable declared with an access modifier will not compile. In fact, there is only one modifier that can ever be applied to local variables—final.
Let us refresh all that we have seen in this chapter in a table form.
Previous Chapter: Chapter 3 - Enums
Next Chapter: Chapter 5 - Other Modifiers (NonAccess Modifiers)
An Access Modifier is a key word in java that determines what level of access or visibility a particular java variable/method or class has. There are 4 basic access modifiers in java. They are:
1. Public
2. Protected
3. Default and
4. Private
Private is the most restrictive access modifier whereas public is the least restrictive. Default is the access protection you get when you do not specifically mention an access modifier to be used for a java object.
Java programming does not run by just a single piece of class that has the whole functionality. You have hundreds of classes that interact with one another, passing data between them and returning output to the user of the system. So it is very important for members of one class to access members of another. Here members may refer to variables, methods and even classes. So, this is where the access modifiers come into picture. The modifier associated with every member of the class determines what level of visibility that member has.
Let us say you have a Class A and you are trying to access a method from inside Class B. If the modifier for the method inside class B is restricted (say private) then the compiler will punch you in the face and tell you that what you are doing is wrong. Because, class A is not even supposed to know about the private members of class B and you cant possibly use them.
You need to understand two different access issues:
• Whether method code in one class can access a member of another class
• Whether a subclass can inherit a member of its superclass
The first type of access is when a method in one class tries to access a method or a variable of another class, using the dot operator (.) to invoke a method or retrieve a variable
Ex:
public class Dad {
public String getName() {
return “Vijayakumar”;
}
}
public class Son {
public void findDaddy() {
Dad obj = new Dad();
System.out.println(“The name of Sons Daddy is : “ + obj.getName();
}
}
Do you think the above code will work? Yes it will. That is because both the Dad and Son classes are public and so the Son class can happily access the Dad class and most importantly, the method getName() inside the Dad class is also public which means the Son can happily access that method too.
Let us say the getName() method was private, then the Son wouldn’t be able to access this getName() method and the compiler would have spit out error messages.
Public Members:
If a variable or method is declared public, it means that it can be accessed by anyone or any other class (irrespective of which package they are in). Of course, it is mandatory that the class inside which the public method is placed is visible in the first place for the method or variable to be visible. You can check out the code example in the previous paragraph for an example. The method from Dad class is visible and available for usage inside the son class.
For a subclass, if a member of its superclass is declared public, the subclass inherits that member regardless of whether both classes are in the same package.
Ex:
package pack1;
public class Parent {
public String getName() {
return “Parent”;
}
}
Package pack2;
Import pack1.Parent;
Public class Child extends Parent{
Public String getParentsName() {
return getName();
}
}
If you see the example above, the child class is able to access the parent class’s method getName() even without instantiating an object of the parent because it inherits the Parent class and all its method as part of the inheritance (extends) feature.
Private Members:
Members marked private can’t be accessed by code in any class other than the class in which the private member was declared. Let’s make a small change to the Parent class from an earlier example.
package pack1;
public class Parent {
private String getName() {
return “Parent”;
}
}
Now the getName() method is private and is not visible from within the Child class and the same piece of code would throw up the below compilation error when you try to compile the class.
cannot find symbol
symbol : method getName()
This error method looks as if the method getName() does not exist at all. Of course the method exists but unfortunately it is declared private and hence no class (except the class that has the exact code written into it) can access it. This includes a child class that extends the parent class that has the method.
Note: You can write a method inside the child class that has the same name as the private method in the parent. This does not account as Overriding because the parent class method is not even visible and hence it is just another method and is not considered overriding.
Tip: Though you may feel that public is better because all other classes can access your methods, that is seldom the case because a code that is visible to all other classes is not secure and that is not the best way to write your code. It is always best to provide just the appropriate level of access to methods and variables instead of having all of them public.
Protected and Default Members:
The protected and default access control levels are almost identical, but with one critical difference. A default member may be accessed only if the class accessing the member belongs to the same package, whereas a protected member can be accessed (through inheritance) by a subclass even if the subclass is in a different package.
Take a look at the following two classes:
package certification;
public class ClassOne {
void testIt() { // No modifier means method has default access
System.out.println("ClassOne");
}
}
In another source code file you have the following:
package otherCertification;
import certification.ClassOne;
class ClassTwo {
static public void main(String[] args) {
ClassOne o = new ClassOne();
o.testIt();
}
}
As you can see, the testIt() method in the first file has default (think: package-level) access. Notice also that class ClassTwo is in a different package from the ClassOne class. When you compile the ClassTwo.java file you will get an error like below:
No method matching testIt() found in class
certification.ClassOne.o.testIt();
From the preceding results, you can see that ClassOne can’t use the ClassTwo's method testIt() because testIt() has default access, and ClassOne is not in the same package as ClassTwo. So ClassOne can’t see it, the compiler complains.
Default and protected behavior differs only when we talk about subclasses. If the protected keyword is used to define a member, any subclass of the class declaring the member can access it through inheritance. It doesn’t matter if the superclass and subclass are in different packages, the protected superclass member is still visible to the subclass. This is in contrast to the default behavior, which doesn’t allow a subclass to access a superclass member unless the subclass is in the same package as the superclass. (See the example above)
Whereas default access doesn’t extend any special consideration to subclasses, the protected modifier respects the parent-child relationship, even when the child class moves away (and joins a new package). So, when you think of default access, think of package restrictions. No exceptions at all. But when you think protected, think package + kids. A class with a protected member is marking that member as having package-level access for all classes, but with a special exception for subclasses outside the package.
Tip: Remember that Default and Protected access is the same as long as inheritance is not involved.
Local Variables and Access Modifiers
Can access modifiers be applied to local variables? A BIG NO!
There is never a case where an access modifier can be applied to a local variable, so watch out for code like the following:
class Test {
void doTest() {
private int x = 7; //Not Possible
this.doSomethingElse(x);
}
}
The above code will not compile or run. Dont think that the private keyword is legal inside the method doTest().
You can be certain that any local variable declared with an access modifier will not compile. In fact, there is only one modifier that can ever be applied to local variables—final.
Let us refresh all that we have seen in this chapter in a table form.
| Access Modifiers – Access to Class Members | ||||
|---|---|---|---|---|
| Visibility | Public | Protected | Default | Private |
| From Within the Same Class | Yes | Yes | Yes | Yes |
| From any class in the Same Package | Yes | Yes | Yes | No |
| From a sub-class inside the Same Package | Yes | Yes | Yes | No |
| From a sub-class outside the Package | Yes | Yes (Only through Inheritance) | No | No |
| From a non sub-class outside the Package | Yes | No | No | No |
Next Chapter: Chapter 5 - Other Modifiers (NonAccess Modifiers)
Labels:
Access Modifiers,
default,
Java,
member access,
private,
protected,
public,
SCJP,
SCJP Certification
| Reactions: |
Saturday, January 1, 2011
Chapter 1: Refreshing Java
We begin our quest of the Java Programmer certification with refreshing what we know about java.
• Java is one of the most popular programming languages
• It can be used to create stand-alone or enterprise class applications
• It is an object oriented programming language
Some of the key terms we may be using throughout this series are:
• Class - A Class is a Template that describes the kinds of state and behavior that objects of its type support
• Object – Objects get created at runtime. At runtime, when the Java Virtual Machine (JVM) encounters the new keyword, it will use the appropriate class to make an object which is an instance of that class. That object will have its own state, and access to all of the behaviors defined by its class.
• Methods – These are pieces of code surrounded by a pair of flower braces “{}” and containing a name. They may or may not take arguments. These arguments would be used by the method for its processing
• JVM – Java Virtual Machine – This can be considered the system in which all the java program code you write will get executed
• Keyword – A keyword is nothing but a word in English but one that has a specific meaning in the java programming language. It can be considered similar to a command that instructs the JVM to perform a certain action. For Ex: the new keyword tells the JVM to create an object of the class on whom the action is performed
• JDK – Java Development Kit – This is the piece of software that needs to be installed in your computer if you want to run Java programs
• Interface – An Interface can be considered similar to a skeleton that defines a broad type pattern that must be adopted by all its children.
If you are unable to understand any of the keywords, don’t worry they will be taken up in detail when we go through further articles in this SCJP Series.
Lets get down to business. Click on the Next Article Link to read the next article in this SCJP Series.
Previous Article: SCJP An Introduction
Next Article: Chapter 2 – Declarations
• Java is one of the most popular programming languages
• It can be used to create stand-alone or enterprise class applications
• It is an object oriented programming language
Some of the key terms we may be using throughout this series are:
• Class - A Class is a Template that describes the kinds of state and behavior that objects of its type support
• Object – Objects get created at runtime. At runtime, when the Java Virtual Machine (JVM) encounters the new keyword, it will use the appropriate class to make an object which is an instance of that class. That object will have its own state, and access to all of the behaviors defined by its class.
• Methods – These are pieces of code surrounded by a pair of flower braces “{}” and containing a name. They may or may not take arguments. These arguments would be used by the method for its processing
• JVM – Java Virtual Machine – This can be considered the system in which all the java program code you write will get executed
• Keyword – A keyword is nothing but a word in English but one that has a specific meaning in the java programming language. It can be considered similar to a command that instructs the JVM to perform a certain action. For Ex: the new keyword tells the JVM to create an object of the class on whom the action is performed
• JDK – Java Development Kit – This is the piece of software that needs to be installed in your computer if you want to run Java programs
• Interface – An Interface can be considered similar to a skeleton that defines a broad type pattern that must be adopted by all its children.
If you are unable to understand any of the keywords, don’t worry they will be taken up in detail when we go through further articles in this SCJP Series.
Lets get down to business. Click on the Next Article Link to read the next article in this SCJP Series.
Previous Article: SCJP An Introduction
Next Article: Chapter 2 – Declarations
Labels:
Java,
Refreshing Java,
SCJP,
SCJP Certification,
Sun Certification,
Sun Certified Java Programmer
| Reactions: |
Sun Certified Java Programmer – SCJP
Java is a very powerful language and is being used by many programmers around the world (including me) to develop enterprise applications. The base of the whole J2EE Universe is plain old Java. Java is one of the most powerful object oriented programming languages ever created (Though some people using other languages might disagree) With so many people who know java available in the job market, an employer would like to know how knowledgeable his prospective employee is in the language. In such cases a certification from the company that created the language would be very useful indeed.
Sun Certified Java Programmer or SCJP is the most fundamental certification for Java Programmers. The purpose of the following series of chapters is to help programmers who aspire of becoming a Sun Certified Java Programmer succeed in their goal.
Next Article: Chapter 1 – Refreshing Java
Happy Reading!!!
Sun Certified Java Programmer or SCJP is the most fundamental certification for Java Programmers. The purpose of the following series of chapters is to help programmers who aspire of becoming a Sun Certified Java Programmer succeed in their goal.
Assumption: This series is written with the assumption that anyone who wishes to take up this exam would have the basic fundamental knowledge of the Java Programming language. We do not begin with what is Java or how to write a class. It is assumed that you know what java is and know how to write, compile and execute a Java program.
Next Article: Chapter 1 – Refreshing Java
Happy Reading!!!
| Reactions: |
Subscribe to:
Posts (Atom)
© 2013 by www.inheritingjava.blogspot.com. All rights reserved. No part of this blog or its contents may be reproduced or transmitted in any form or by any means, electronic, mechanical, photocopying, recording, or otherwise, without prior written permission of the Author.
