import java.util.*;
public class one{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int a = sc.nextInt();
System.out.println(a);
}
}
- Java is a compiled language.
- How java is executed
Write the source code for your program in .java. The compiler checks for errors and if all passes, it converts .java to Java bytecode. This is sent to the JVM which reads and runs the bytecode
To compile, javac class_one.java - this will get the class_one.class bytecode - this is the compiled code. Then, start the jvm using this class_one.class file (java class_one)- the jvm converts this to machine code.
the jvm is just a specification - a set of rules that define how the bytecode must be converted to machine code.
- Create a new instance of the Dog class :
Dog mydog = new Dog(name, size);
- Java has lists!
int[] list_one = {1, 2, 3, 4};
- Typecasting in java. Str to int: int a = Integer.parseInt(‘8’)
A source file has a class, the class has methods and variables. the methods have commands.
- When you say class_one.class at the cmd, the JVM look for the main() method and executes it.
**The main() method must be inside a class obv. public static void main (String[] args){ //code here }
NORMAL CLASS DEFINATION : public class ClassOne{
} public - everyone has access to it. class - syntax declaring that this is a class
main()’s void - this means it returns nothing
The main() method accepts an array of strings as argument and it MUST be called args - these are the arguments given to the jvm when the class is called - java JavaOne ab de og so, args will be [“ab”, “de”, “og”]
- The source file must be named after the public class in it. For eg, I create a class ClassOne with the main() method, I cannot call that file one.java, I have to call it ClassOne.java
- Java has 3 looping commands - while, do-while, for
- Java has only one main to get the ball rolling. However, the test classes you write to test other classes might have main()s.
- YOU WILL HAVE LEARNT A GREAT DEAL WHEN START LOOKING FOR WHY THE CODE ISNT WORKING AS EXPECTED AND YOU FIND OUT THAT IT WAS BECAUSE OF TWO GARBAGE COLLECTORS THAT DIDNT KNOW ABOUT ONE ANOTHER.
- if (condition){ //code
}
- Break the python habit of putting colon after the if condition, also, don’t forget the semicolon after the statements. Also, remember that everytime you need to create a list you do int[] a, String[] s etc
- Length of that list : aa.length
Accessing the elements : aa[1] - 0 based indexing
- Type casting int one = (int) 24.3 - it always rounds down.
- String a = “blah”; int a = 12 –> wont work. This is not Python :P
- Two types of languages - compiled and interpreted.
Java is a compiled language - the compiler gets the bytecode from the source code - makes it fast Python - the virtual machine converts the source code directly into machine code - makes it slower.
Java is a Strongly typed language - this means that it cant allow variables to hold the wrong type of data. eg: String a, int a example above in #15
Java supports dynamic binding - that means that there will be objects created at runtime, they can hold variables,data. Compiler makes sure you aren’t accessing private methods, chaging variables that arent meant to be changed etc.
Procedural programming - this style of programming imply contain a series of computational steps to be carried out. Any procedure can be called at any point in the program
True OO code will have this property : if you have to add a new feature, you wont have to touch previous tested code. EXTENSIBILITY !
- A inherits from B. B is the super class, A is the subclass.
Objects in Java have instance variables and methods
- create a new class Dog:
public class Dog(){ public void bark(){ int size = 1; System.out.println(“Bow, Bow”); } }
Now, write a tester class : public class TestDog(){ public static void main(String[] args){ Dog rocky = new Dog(); rocky.bark(); rocky.size = 2; //will give an error, as there is no instance variable called “size”. size is there only in the bark() method } }
- A method has been called just by “void bark()” - whats with that ?
void because the method doesnt return anything. bark is its name.
20.main() can be used to either test your real class, or launch your java application
assembly language === machine language thats false assembly language == LOAD 12A machine language == 110101011010101
- JVM is a specification - a set of rules (protocol) about how the bytecode should be converted to assembly language. The Sun’s version of JVM is written in C. You can use python too to write the jvm. another eg : html is a specification, all browsers implement that specification. YES, there is JVM in Python - PyJVM.
terse - not being verbose, being concise and to the point.
- Scala is an effort to make a “better java”. That is, more terse, functional approach, better design maybe while maintaining the speed that java is loved for. The Scala compiler is used to convert scala source code to java bytecode. This byte code can then run on any standard jvm (which runs Java bytecode too). Since Java runs on the JVM, Java and Scala stacks can be freely mixed for seamless integeration.
Scala classes are ultimately JVM classes. You can create Java objects, call their methods and inherit from Java classes transparently from Scala. Similarly, Java code can reference Scala classes and objects. use a scala complier then
- You can make objects in two steps too -
Player p1; –> tells the jvm to allocate space (on the stack) for a reference variable (to store the object reference/pointer/address) p1 = new Player(); - tell the jvm to allocate space for the object on the heap and assigns the reference to the reference variable
- Class methods can access the class instance variables. Typical design pattern :
public class ClassOne(){ public static void main(String[] args){ GameClass game = new GameClass() game.startgame() –> you are calling the stargame method of the game object. this method will use the class’s instance variables. } }
- The java objects goes to an area called heap - it is a garbage collectible heap
- there is not “global” variable/method in java. But, declaring them as public and static would make them behave like that.
**In any class, in any method, you can access a public static method. If you make a variable as public static final - that is a global constant.
static methods can be accessed in non static methods, not the other way round. [ this is because the static methods dont depend on the state of the object/class. whereas the non-static methods do ] also, the static methdods must be accessed by the name of the Class, not the object - not illegal, but not good pratice.
- packaging/exporting a java application.
A java program is nothing other than class(es) with one having the main() method. when you wish to ship the code, you can bundle your code in a jar file (java archive) and include a manifest file - which defines which class in that jar holds the main() method. You may also need to include a jvm with your jar incase the end user doesn’t have it. there are installer programs that help you package all this together.
- superclass is more abstract. the sub class inherits from it and gives more specific functionality.
- again, java is type-safe - you can’t store a giraffe object reference in rabbit variables.
Two types of variables - priminitives (int, float, String) and object references (Dog fog, Cat fat)
- **Java primitive variable types :
boolean - true or false char - 0 to 65535 eg: char=’d’;
INT : byte = 8bits -128 to 127 short = 16bits int = 32 bits long = 64 bits
8 BITS = -2^7 TO (2^7)-1 X+1 BITS = -2^X TO (2^X)-1
floating point float 32 bits eg: float f = 23.5f - without the f, it defaults to double. double 64 bits
remember them by : be careful, bears should’t ingest large furry dogs - mnemonic - this is in order. be careful, because sakru is large fucking dick
- Keywords - the tokens that the compiler recognizes - eg: this
- there is no such thing as a object variable - only an object reference variable
the char varialbe holds the well, the char. the object reference variable holds the “bits” having the address of the object.
- a Dog reference can only point to a Dog object. But, it can point to different Dog objects in its life. However, it if is declared final - then it cannot point to a different Dog object.
Also, if it is the reference variable is set to null, it points to nothing - (use Dog dog; dog=null - however, it can be used in the future to point to Dog objects) when the last reference variable pointing to a object is set to null, the object becomes a candidate for garbage collection. **the reference variable contains a reference to the object - not the object itself. the object lives on the heap.
34. Dog a = new Dog(); Dog b = new Dog(); This creats two dog objects on the heap.
Dog c = b Now, this wont create a new object, this will paste the address biits in b into c. So, c will point to object refered to b only.
- int[] nums = new int[7]; –the nums referes to the int array object. An int array object can contain only int values. an Dog array can contain only Dog object reference variables.
Arrays are always objects, weahter they are declared to hold primitives or object reference variables. **you can however, put an short in an int array. – this is called implicit widening **a refernce variable has a value of null when you are not referencing any object
eg: Dog[] dog ; dog = new Dog[7] ; –> dog referes to a Dog array object
dog[1] = new Dog();
- objects have behaviour and state (controlled by methods, instance variable)
- Pass arguments this way:
Dog dog = new Dog(); dog.bark(“3 times”);
**The values passed to the method are called “arguments”/”parameters” A method USES parameters, the caller PASSES parameters. A parameter can also be used for a local variable
accept it like this: the int says the the bark() method will return an int. int bark(int a): return a;
assign it to variables like this: int returnedInt = dog.returnInt();
- Java is pass-by-value **passing by value is passing by copy
when you pass an int x to a method, the variable is copied - thus, say the method accepts it as int b - this int b will be a copy of int x. and changin int b won’t affect int x. when you pass reference variables, you pass a copy of the reference variables -so, if you null the original one, the latter one still remains.
- getters and setters in java
say, a class has these instance variables : var1, var2, var3 now, getVar1(), setVar1, getVar2(), … - this is the standard
String getVar1(){ return band; }
void setBand(int a){ int band = a; }
- encapsulation
till now, we were leaving our instance variables exposed. use getters and setters to force other code to access them by setting them to private and setting the getters and setters to public eg : public void setHeight(int ht){ if (ht>9){ height = ht; } else System.out.println(“Invalid height”); } so, int size = 43; becomes private int size = 43;
–> this is like decorators in Python no? yes, this allows you to do some pre processing on the method arguemnts (can be validation, logging) just like the decorators.
- public and private are called access modifiers.
- **instance variables always get a default value - even if you don’t initialize them.
char/integers = 0 floating points = 0.0 booleans = false reference = null Strings = null
There is a difference between instance and local variables - local variables dont get a default value - they must be initialized before being used. these are the variables that are defined inside a method.
- two primitives are the same if they contain the same value.
two reference variables are same if they contain the same address - that they reference the same object. compare two objects using the .equals() method
- Great idea !
Write the pseudo code first. Then : **Write your tests first. then, write the code to pass those tests. writing the tests first makes you think hard about how you want to design the app. then, write some more tests, and just the code that passes those tests. doing this will make sure your app always builds.
The test class usually has the main() method - to instantiate the required objects and run them.
- new way to loop in java: introducing the “for each”
int[] arr = new Int(10); for (int cell: arr){ System.out.println(cell) }
this is different from the earlier one: for (int a=0;a<=10;a++){ //code }
- when you want to make some class inherit other class, don’t pass that class as an argument to that class but write class Dog extends Animal{ //code
}
- int a = Integer.parseInt(“3”); –> note, we are using the Integer class, not the int primitive datatype.
here, we are using the Integer class’s parseInt method which takes an string and returns an integers
- Use BufferReader to take in the user input
for eg :
import java.io.*; BufferReader br = new BufferReader( new InputStreamReader(System.in)); String line = br.readLine();
**OQ: what is the difference between BufferReader and Scanner? One is in java.io and the other is in java.util
- use the for loop when you know exactly you want the thing to run. use while when you dont.
- You can create an instance of the class(object of that class) inside the class itself. you can use that object to call the methods of that class.
eg: public class Output{ public static void main(String[] args){ Output ou = new Output(); ou.go(); }
void go(){ System.out.println(“Inside the go method !”) } }
You cannot do this in Python. eg: class Output(): a = 3 def b(self): print self.a c = Output() print c.a c.b() This only works. shifting the last three statements inside the class defination does’t work.
- the traditional arrays - int[] a = new int[4]; cant change their size.
- introducing ArrayList ! –> this has dynamic size, as you remove items from it, it reduces in size. you can query it for things and ask them be returned. This is the closest to the Python list yet.
It has: .add(object element) .remove(object element) .remove(index int) .contains(object element) .isEmpty() ->true if empty size() ->len(list) get(int index) - >list_[int index] indexOf(obejct element) –> list_.index(“a”)
- Make it like this :
ArrayList<Dog> dog_array_list = new ArrayList<Dog>(); You can add Dog objects to it : Dog dog1 = new Dog(); dog_array_list.add(dog1); dog_array_list.index(dog1); dog_array_list.contains(dog1); dog_array_list.remove(dog1); dog_array_list.isEmpty();
to remove items from the ArrayList, you can use .remove(object/index) but, to remove from an array, you have to do : String[] s = new String[5]; s[1]=”aa”; s[1] = null; –> this will remove it.
ArrayList lies in which package? **OQ in an int ArrayList, if you have to remove element 1, which is at index 0, you do .remove(0) or .remove(1);
ArrayList belongs to the java.util package
ArrayList is an object. so, you can invoke/call all these methods. to be fair, array is also an object but you have to use special methods to interact with it.
the traditional array doesn’t return things. when you do : Dog d = dogArray[1] -> you did not remove the dog from the array, you just copied the address bits (the pointer/reference to the Dog object being refered to) and put them in d. Now, both d and dogArray[1] point to the same Dog object on the heap.
ArrayList cant hold primitives just like that, it wraps them in a primitive wrapper.
- The or is ||
not is != or !a.equals(b)
55 **short circuit operators. && and || the jvm will check for the left hand side condition first and if it is false, wont bother to check the right one. if the left one is true, wont check the right one
& and | are non short cut operators.
- chatAt method
“abcd”.charAt(2) –> c
- in the java library (java api) classes are grouped into packages
each class belongs to a package - eg of packages: javax.swing, java.util - it holds the utility classes.
java.lang package contains the Math (Math.random()), System classes. import java.util.ArrayList or type the full name each tome you use it. eg: java.util.ArrayList<Dog> dog = new java.util.ArrayList<Dog>
- uses of packages : it provides structure to the api,
it provides name scoping so there is no clash between class with same names but in different packages. provides security.
javax.swing - holds some gui related classes - same with java.awt packages that start with javax were initially extensions then were promoted to standard packages. java.lang package is imported by default. Impporting does not make your code bulky or slow, nor does it make the program bigger. it only and only is a mechanism to not have you write the full class name everytime you have to use it.
59 **when an ArrayList is created to hold Dog obejcts, it can hold the subclasses of Dog objects too. children can go where the parents are expected. this works because the children are expected to have all the functionality that the parent has. it may have it in a more specific way(it may override some methods), or it may have extra functionality(it may have new methods), but it cannot have lesser functionality
- abstract code is generic code. it is general. specific code gives more personalised behaviour to classes/objects.
When we wish to say that the sublclass inherits from the superclass, we say the sublclass extends the superclass.
- the lowest method gets called i.e. one closes to the object - the one which it iteself or its immediate parent overriides.
- **to check if one object extends the other, it should pass the IS A test
eg: triangle IS A shape. human IS A animal
- **HAS A relationship : eg: bathrom has a tub
in this case, dont make the bathroom extend the tub, rather it implies that bathroom class should have tub object reference. ie in bathroom defination: Tub tub = new Tub(); Sink sink = new Sink();
- when overriding the superclass’s method, you may wish to not complete obliderate it, rather add to it. so, use this:
public void hello(){ super.hello(); //do more }
**OQ: contrast this with: public void hello(){ //do something super.hello(); } How are the two different
- What are the memebers of a class :
they include instance varialbes and methods So, a superclass can choose weather or not it wants a sublclass to inherit a particular member (method/variable) **the four accesss levels in java: private, default, protected, public
access levels control who sees what. public methods are inherited, private methods arent
- inheritence allows you to define a common protocol that all your sublcasses have to follow.
Polymorphism : when you deinfe a supertype for a group of classes, any subclass of that supertype can be passes where the supertype is extected. so, A extends B. in some place, java expects B(superclass) to be given, there, you can sneak in A (its)
- **the threee step procedure behind this statement
Dog dog = new Dog(); i. create a reference variable called dog (pointing to null currently) - in the stack ii. create a new Dog object - in the heap iii. link the Dog object to the dog reference variable (make dog point to the Dog object)
Polymorphism means that you can ask a animal reference variable to point to a Dog object (since the Dog object is just a specific type of Animal object.) So, this is perfectly legal : Animal myDog = new Dog() here, we are making the myDog reference varialbe point to the Dog object.
Hence, **with polymorphism, the reference variable type can be a superclass of the actual object type it referes/points to. So, this is now possible:
ArrayList<Animal> animal_array = new ArrayList<Animal>(); or, lets keep it simple. Animal[] animal_array = new Animal[4]; animal_array[0] = new Dog(); animal_array[1] = new Cat(); animal_array[2] = new Lion(); animal_array[3] = new Tiger();
Now, when you do animal_array[2].makeNoise() –> you will get Lion’s roar.
ALSO, you can polymorphic arguments and return types. eg, a method is expecting a Animal object as parameter, you can give it Dog instead. same when returning things. when a method promises to return Animal, it can legally return Dog too.
HENCE, IN ALL CASES, IN ALL SITUATIONS, SUPERCLASS AND SUBCLASS ARE INTERCHANGABLE ONE WAY- WHERE THERE IS SUPERCLASSES NEEDED, SUBCLASS CAN BE USED.
This is cool because you can keep superclass as the return/argument required type. then, you wont break the code when a new class subclasses the current class, because that new sublclass’ can be passed to the old methods and the code will still work. With polymorphism, you can write code that doesnt change when you add a new subclass
- Classes cant be marked private like methods.
but there are three things that can preven you from extending a class: if it is not explicity marked public **public classes are the classes that are availabe to code outside the class’s package as well. so, it can be subclassed only by other classes in its own package.
the keyword final - this makes the class non-extendable/inheritable. nobody can inherit a final class. ERROR: Exception in thread “main” java.lang.VerifyError: Cannot inherit from final class
**if the class has only private constructors - it cant be subclassed or instantianted outside itself.
you may need to make classes final if you want a gurantee that they would always behave a particular way.
- there is a difference between overloading and overriding.
if is overriding when you honour the parent method’s parameters and return values restrictions. i.e. accept the same as the parent did, return the same as the parent did.
But, if you modify the parameter/return value and still use the same name for the method as your superclass, it is defined as OVERLOADING
- make sure that the method you are overriding with has the same access level or friendlier. if you are overriding a method decalred as public in the superclass, you cant mark it as private in your overridden version or even not expilicty put “public” in the method deination, because that will default to “default”.
- method overloading is more flexible. you can change the parameter signature, return type etc. you can vary the access levels in any direction. **when overloading, changing only the return type is not allowed. you must also change the argument signature else, it will be classes as overriding.
SO, overloading is officially, technically: “explicitly changing the argument signature of the method while keeping the same name” - you may not change the reuturn signature, but the parameter has to change for it to be overloading.
Look at it this way, class A has one(), B extends A, B overrides one() –> the same argument and return type This will work. the compiler wont allow us to change the return type of B’s overriden one() because remember we are giving the promise of polymorphism to the users. we will be able to pass the B’s overriden method where A’s original method was expected. the return type cannot change in the new method, otherwise the existing code will break.
Now, say, we want B to overload A’s one() and not override it. This is cool, we can do it, but we will have to change the argument signature, AND/OR the return signature. This is because if we dont change the argument signature compulsarily, how will the compiler know weather to call B’s overloaded method or A’s original method. When B changes the parameter signature, the compiler knows what the developer intends to be called.
two methods can be said to be overloaded if they are in the same namespace. so, if Dog extends Animal, and both have a makeNoise() method with different parameter signature and return signature, then it is overloading. If a class has two methods with the same name (needs to have different parameter/return signature) then, it is method overloading. however, if there are two classes not linked together and they have methods with the same name, that is not overloading. basically, they have to be in the same namespace to qualify as method overloading.
Remember when answering questions that : subclasses can come where the superclass is expected[“”polymorphism”“]. , smaller capacity variables can come in the place of larger variales (where int is required, you can use byte)[“”implicit widening”“] Also, know the overriding is when you respect the parameter and/or return signature of your superclasses version. overloading is when you change the parameter signature.
**Method overloading need not happen within the same class. A extends B. Now, A can overload B’s one as well. CHECK if this is overloading, using the @Overriden tag
it is illegal to just change the return signature - if your superclass returns an Animal, you have to return Animal/Dog/Cat etc but you cannot return Plant. If you do want to return Plant, you will have to change the parameter signature too.
- So, you make abstract classes and make more specific verision in their subclasses, whihc are usuable. but it makes no sense to instantiate the abstract superclass since it would not implement any real functionality, just provide some policy/blueprint for subclasses extending it. So, to prevent the abstract classes from getting instantiated (Animal a = new Animal(); shouldnt be allowed) - we mark them as abstract.
This way:
abstract class Animal{ //code } SO, effectively, an abstract class has no usage untill it is extented.
prevent a class from being extended - final or mark the constructor private **whats the difference between the two? if you mark the constructor as private, the class cannot be instantiated outside itself. nor can be extended. if you mark the class as final, the class cannot be extended, but it can be instantiated outside
in contrast, to make sure the class is extended, and cant be used without extending - mark as abstract
So a abstract class meants that that class MUST be extented. An abstract method means that it MUST be overrideen. it has no body, it just defines the parameter and return signature. eg: public abstract void eat(); - end with a semi colon, no body. Note, this is different from a empty method. public void eat(){} //this is an empty method. this method can be called with overriding and the class doenst have to be marked as abstract if this method is present.
If you have even one abstract method is a class, you have to mark that class as abstract. this is because if it isnt extented and used as is, when the abstract method is called, it will blow at runtime. However, for a abstract class, it can have concrete methods as well as abstract methods.
SO, ABSTRACT CLASSES AND METHODS ARE USED explicitly TO DEFINE PROTOCOLS. all abstract methods must be overriden by the subclasses.
- so you cant make objects of abstract classes like Animal. Okay, so this isnt allowed:
Animal animal = new Animal(); –> WRONG But, consider this: Animal[] animals = new Animal[5]; —> LEGAL ! THis is allwoed because you are not creating a new Animal object here, you are creating a new array object of type animal. it can be used to store Dog objects, cat objects etc.
- every class of java extends the object class.
Any method with object as its accepted/returned argument can accept anything! eg : ArrayList.indexOf(), .add()
some methods of the object class: equals(Object o), hashCode(), toString(), getClass()
so:these work out of the box : Dog d = new Dog() d.equals(“1”) - false d.hashcode() d.getClass() –> will give class Dog d.toString() –> prints the name of the class and some number
you can ovveride some of the methods in the object class. like hashCode() etc, but those methods that are marked as final, cant be overridden
class Object is not abstract - that means that you can make an object of the Object class - it is used in thread synchronization.
Why not exploit polymorphism and make all methods accept and return object type? then they can use any object – this would destroy type safety.
**you cant call the subclasses methods from the super class object. you can call only the methods defined in the superclass iteslef or in the class it inherits (read the object class)
One caveat - when you declare an ArrayList for type Object: ArrayList<Object> ar_ob = new ArrayList<Object>(); you can give any object to ar_ob - but when you use .get(0); to get back the object, it always returns as object. You enter Dog, it comes out as an object of Object class.
This is just like saying Subclasses can be used where superclasses are expected but not the other way around. So, this also wont compile :
Dog old_dog = new Dog(); Dog dog = getObject(old_dog); –> wont work, the dog comes out as object. and the Object object cant be assisned to its child.
”” You cant assign a parent object to a child type reference variable. So, Dog d = new Animal() wont work Animal a = new Dog() works “”
THIS WOULD WORK: Object dog = getObject(old_dog);
public Object getObject(Obejct c): return c;
you can call a method based on the reference variable type, not on the object type. as the reference variable points to a class of same name or lower, we won’t be able to call the methods belonging to the child but can call methods belonging to the parent so, Object o = new Dog(); o.bark() - wont work This wont work becuse Object class donest have the bark method. IF it has the bark method defined, then it would have worked - but here, the compiler would have called the overriden methon in the Dog class.
So, the subclasses can access their parents methods(or the more specific version fo their parents ones in case they are overriden) plus their new methods but the parents cant access their childrens methods - because this would be us exploiting the polymorphism guarantee - code would start breaking left and right and the extensibility promise would vanish.
You can ofcourse cast the generic Object object to a Dog object: so, the previous incorrect line can be fixed by : Dog d = (Dog) o d.bark(); –> this will work
Hence, last time, when we created the Animal array to hold Lion, Dog etc, it worked. So, this worked: Animals[] animals = new Animals[2]; animals[0] = new Dog(); animals[1] = new Lion(); animals[0].makeNoise(); BOW BOW animals[1].makeNoise(); ROAR
But, this wont work: Object o = new Dog(); o.makeNoise(); –> error Dog d = (Dog) o; d.makeNoise(); BOW BOW
This is because Object method doesnt have the makeNoise method for Dog to override. The makeNoise method was first defined in Dog subclass - hence, this is a case of a parent trying to access the method of a child - NOT ALLOWED.
However, Animal class has the makeNoise method that the Dog class overrides - hence, you can use the Animal reference variable and call that method - the latest method is called - the overriden one, the one in the Dog class.
**you can check if any object belongs to a class using the instanceOf operator if (o instance of Dog){ Dog d = (Dog) o; }
this is not working. how to do this correctly ? **OQ
Some terminology : reference variable - the varialbe which holds the address bits to point to a object on the heap. so a reference variable of Class Dog can point to Dog objects on the heap or any of Dog’s subclasses.
Summary: if any reference variable of type “object” doesnt have a method defined but its children have it, you cant call it using that reference variable. if the class has it , but its children have a more specific verison and the reference type is that of the superclass, the more recent veriosn is called.
COMPILER CHECKS THE CLASS OF THE REFERENCE VARIABLE, NOT THE CLASS OF THE ACTUAL OBJECT THE VARIABLE IS REFERING TO.
SO: Animal a = new Dog() ; imagine both Animal and Dog class have the method Bark() if you call it on a, a.Bark() will return the overriden methond by the Dog class.
If Dog class has a new method, fetchBall(), then you cannot do : a.fetchBall() because the compiler checks if the class of the reference variable (the reference variable is a here, its class is Animal) has that method - and not the actual object being refered to (that is the Dog object) - so as Animal doesnt have that, this results in error. In effect, it boils down to the parent trying to call the methods of its children, this is not possible. the children can call the methods of the parents.
- Sometimes, you need to inherit from two superclasses. this insnt allowed in java. so, you use interfaces.
Deadly diamond of death is when you have a class digitalRecorder with two subclasses CDBurner and DVDBurner. Now both of if you could inherit from both of these calsses, which classes method to be called from both the parents.
the three solutions proposed : give all pet methods to animal - this is not good as non pets will have access to pet method
give all pet methods to animal - make them as abstract - this is silly because the non pets will have to override all the pet methods albeit by just saying - do nothing.
putting the pet method in just the pet sublclasses of animal - this is redundant again. you are not using polymorphism - you have to write the methods everywhere -also you have to make sure that all the subclasses get it exactly right so that it does not lead to inconsistent behaviour.
Java interfaces are just like 100% pure abstract classes - all its methods are marked abstract. so, if you implement an interface, you will have to override the methods in that interaface and hence, the compiler will call the overriden methods - avoiding the deadily diamond of death.
define it like this : public interface AnInterface{ public abstract void MethodOne(); public abstract void MethodTwo();
}
use it like this: public class Dog extends Animals implements Pets{ //override MethodOne and MethodTwo here. }
**interaces are just like you are extending two classes. so, all the rules of polymorphism apply here as well. that is, if you define a method that has the interface in its return/parameter signature, you can use any class that implements that interface in its place. so, now you can accpet classes comming from completely different inheritence trees !
A CLASS CAN IMPLEMENT MULTIPLE INTERFACES !
public class Dog extends Animal implements Pet, savable, paintable { //code //make sure to override all the methods of all the interfaces }
Single parent only (superclass) - it defines who you are multiple interfaces - define roles you can play
You have an object - when you want to make a more specific version of that object, you subclass the new object and override/add new behaviours to that object.
When you want to define a protocol for a group of classes, i.e. when you want the group of classes to positivly have some methods, mark the class as abstract and make the sublcasses extend it.
When you want to define a role that other classes can play, regardless of where they come from in the inheritence tree, use interfaces.
from the Dog object, if you wish to call any of Animals method, use super.theMethodName(); imagine you are in a sublclass which inherits some methods from its superclass. you can use super.methodName() to call the method of the superclass, and use this.methodName() to call the overriden method.
When to choose any class as abstract or normal concrete class - use abstract when the class is generic enough that it cannot be used without further modifying it and making it more specific.
Remember: **when you dont want a class to be instantiated (just inherited, maybe because the original class is very generic and wont be of use unless extended) you mark it as abstract. if the class has even one abstract method, it must be marked abstract
so, in Animal d = new Dog(); there are two variables. the reference variable (d) - it has type Animal and the object beign refered to - Dog here. Now, on d, you can run only the methods define in Animal or above. not the ones defined in Dog. (parents cant call childrens methods)
naturally, all interface methods are public and abstract. naturally, you cannot instantiate an interface - only implement it.
- the way to kill the object is to abandon it.
The object live on the heap. The method invocations and local variables live on the stack. Local variables are aka stack variables.
instance variables are declared inside a class, local variables are declared inside a method, they include the method parameters.
the stack has stack frames - one for each method. the current running method has its stack frame at the top. the stack frame stores the state of the method and also the local variables
so, imagine that a method a calls b, then b calls c. so, c is on the stack, gets popped off, b comes up, then a. reference variables also live on the stack, the objects they point to live on the heap
Instance varialbes live on the heap - inside the object they belong to. if an object contains a nonprimitive variable (reference variable) –> then the reference variable lives in the object but the object being refered to lives on the heap Animal a; –> this just creates the reference variable – it points to null this a lives on the heap if it is an instance variable or it lives on the stack - inside the stack frame if it a local variable. a = new Animal(); –> this creates a new object Animal on the heap and the reference variable is given the address bits to point to the object.
When you create a code, its constructor gets executed. the constructor has the code that runs when you instantiate an object. if you dont write any constructor for yourself, the compiler writes one for you public Duck{
} – note it has no return type.
constructor can be used to initialize the instance variables - now you dont have to write a seperate setter method for that.
Constructors are not inherited. You can have more than one constructors (overloaded constructors) - they can be differencaited based on the parameter signature. you can have 2 constructors that accept the same arguments but only if they are passed in different order.
constructors dont have to be public, they can be private or default( by default, they dont have any access modifier at all; its just Duck(){};
**there is a difference between public Duck(); and public Duck(){}; In the first one, the method Duck is not defined. It is abstract. In the second one, the method is defined but it just doesnt do anything however, the first one has to be marked abstract to be compilable - public abstract void Duck();
marking anything as private means that nobody outside the class can access that method/variable.
- **say a object a inherits b which inherits Object class.
Now, when the object a is created on the heap, the object a has inside it object b with all its instanec variables and also Object object inside the b with all its instance variables.
**all the constructors in an object’s inheritence tree are run in order when you make a new object. so Dog d = new Dog(); –> runs the Animals constructor and also the Objects constructor. even abstract classes have constructor (even though they are never instantiated) so, whenever any object is created anywhere in the code, of any type, the Object constructor runs (and runs first). this is because the subclass depends on the instance variables and methods of its superclass to function correctly. This is called constructor chaining.
so, the stack looks like this :
Dog() –> Dog()/Animal() –> Dog()/Animal()/Object() –> Dog()/Animal() –> Dog()
You can explicitly invoke the superclasses constructor or else the compiler will do it, no worries. do this : **the super(); must be the first statement in every constructor IF present at all. class Dog extends Animal{
int dod_size; public Dog(int size){ super(); dod_size = size;
}
- super() accepts arguments too. eg ;String name=”dog”; super(name);
- Now, say that you have a hundred constructors (all with different parameter signatures/orders). If all the constuctors have some common code, like say printing something/logging the creation of the object etc, you will have to manually write the same code in all the different constructors. Or : you can put it in one place - the Real Constructor and invoke it everywhere, then complete the custom constructor operations and get the object ready. – use this() for this.
this is a reference to the current object.you can say this() only within a constructor. you cant have both this() and super() in one constructor - they both must be the first statements in their respective constructors. So, do this :
Class Dog extends Animal{ int size; String dog_name;
public Dog(){ this(“Rocky”); //more specific initialization now goes here }
public Dog(String name){ –> this is the real constructor. super(); //calls the constructor of Animal //log code //print code dog_name = name; //more generalization code here. } }
**what is ‘this’ used for? OQ. it refers to the present object, just like self in python
- an objects life depends on the life of the reference variables pointing towards it. the life of the reference variables in turn depends on weather they are local or instance variables.
Say a method is defines a local variable “a”. Now, that variable “a” lives in the stack frame of that method. it is not accessible to code outside the method. they die with the method.
An instance variable lives as long as the object lives. they die with the object.
so, all the methods inside the class can access the instance variables. but the method can also define some variables for its own personal use that no one else can access (its Local variables aka stack variables)
- life and scope.
life is till when is the method alive - till the method is running. scope is where all can the variable can be accessed - so, a variable is defined inside a method A, and that method calls another method B, then the variable defined in A is still alive, just out of scope.
Same rules for both primitives and non-primitive type of variables. An object is alive as long as at least one reference variable pointing to it is ALIVE. (it can be out of the scope, that is allowed, but it needs to be alive just)
example of Three ways that can kill the object: public void go(){ Dog d = new Dog(); }
- this will toast the Dog object because the d reference variable is out of scope and dead after the go() method ends running and its stack frame is popped off.
public void go(){ Dog d = new Dog(); d = new Dog(); –> in this case, the old Dog object is toast. because you reprogrammed your reference variable d to point to a new Dog object. d = null; –> the new Dog object is also toast, because you reprogrammed the reference variable to point to nothing - i.e. effectively removeing the address bits to the new Dog object. }
- **consider this case;
there is a object Dog that lives on the heap. Now, the Dog has an instance variable (non primitive, of type Collar) called c which is programmed to point to a Collar object. Say, the new Collar object has a instance variable (primitive or non, doesnt matter) (the instance variable lives with the object recalll on the heap) - but now, when the c is set to null, the Collar object on the heap are toast and can get GCed. Note on the heap there are two objects here, the Dog object that has the c instance variable and the Collar object that has its own instance variables.
Also, another case : what if like above, we created a local variable to point to a object in the heap, then as soon as the local variable dies (this happens when the method holding the local variable is popped off the stack), the obejct becomes toast.
When a method calls a new method, that called method gets on the top of the stack and if it accepted any parameters, they live with it in its stack frame.
- **when solving java input output questions (or questions of vitaully any type, just look for the main() method and then proceed.)
- Reading this makes it appear that everything is so transitory - how do objects even survive ?
Every java program’s stack starts with the main() methods stack frame on the top, then it calls stuff which call stuff and all, in the end, everyone finishes executing and the main() stack frame becomes active again, it ends running and the program shuts down.
- Now, say the main frame has a local varialbe “a” that reference a Kit object and another local varialbe “c” that references a Collar object. Now, that Kit object has a instance variable Kit_c that is equal to “c” - the local variable. Now, suppose you set “c” to null. this means the Collar object should be toast. But it wont be, because the object Kit is still alive, and the Kit’s instance variable Kit_c is still alive and it points to the object “c” was pointing to - the object Collar.
Collar will die when Kit dies.
public class Example{ public static void main(String[] args){ Collar c = new Collar(); Kit k = new Kit(c); c = null; } }
class Kit{
Collar kit_c;
public Kit(Collar col){ kit_c = col; } }
class Collar{ public Collar{
} }
- **a very powerful way of finding how many objects were created is looking for the “new” keyword. when you say “new”, you call the constructor and create a new object.
- some methods dont need instance variables like Math.round() - also, it is wastage of heap space to make objects of classes like Math class. this is because you what are the obejcts (they just store the instance variable inside them). So, you dont make an instance of the math class, infact you cant.
so, this is illegal : Math mathObject = new Math(); ->you get that Math() has private access, i.e. the constructor is marked as private.
”” Recall, there is an OQ that asks in the section talking about how to prevent a class from being extended: mark it as final, mark its constructor as private, mark all methods as final I asked what is the difference between these approaces:
- marking the class as final
This is the best soultion if you dont want to allow a class to be extended because this has no unnecessary sideeffects.
- marking the constructor as private
this wont let the class be extended sure, but it also wont let the class get instantiated. this is because anything marked private cannot be accessed outside that class.
- marking all methods as final
This wont do the job because this is simply saying, this much part of the class cant be changed. but this doesnt stop anyone from extending the class.
”” Recall Java has this habit of not allowing things that are useless. so, why are non static methods allowed in classes with private constructors. they are can never be accessed! (because static methods are to be used directly from the class name, without instantiating the object)
java rightly doesnt allow abstract methods in classes marked with private constuctors, because even one abstract method means the class has to be marked as abstract and abstract classes cant have private constructors - abstract classes need to have their methods and constructors as public
still, you can use the methods of the Math class - int a = Math.round(2.3); –> that is because the keyword static is used for the method that can run without any isntance of the class.
**the keyword static lets a method run without any isntance of the class. static method means that behaviour not dependent on instance variable - so no instance variable/object required.
normal method :
class One{ int a = 2;
public void useInt(int b){ –> here, the instance variable value affects the behaviour of play() int local_a = a; } }
class One{ public static int min(int a, int b){ –> this method doesnt need the instance variables. //return the lesser of the two } }
**so, a static method is that method that does not need the instance variables to function - hence they can be used with out the isntance variables existing hence, they can be used without the object being created. So, you directly use the class name and not the object name ot call that method.
**two ways of making sure that no one instantiates your class : marking the class as abstract, this means the class has to be compulsarily extended marking the constructor as private –> hence, the constructor becomes inaccessible to code outside the class. this also means that the class cant be extended
so, static methods dont depend on non-static (instance variables) - so,they cannot use them.
**note that the main() method is a static method. it is directly called without creating the object of the class containing it.
regular methods can use static variables and methods, not vice versa.
also, the static methods cannot use non static (regular) methods either. this is because they dont exist. EVEN if they dont use the instance variables. this is because, if in the future, you wish to change the method to make it use the instance variables, your code will break. also, some subclass can ovveride that method and make the method use isntance variables, then it is a mess.
you can invoke static methods from objects too - it is just not advised, makes the code less readable so, this is allowed: Duck d = new Duck(); int a; d.main(a);
So, this wont work: class Example{ int a = 3 //a non static (instance) variable. public static void main(String[] args){ JustAme(); –> static method cant call a non static method, or use a non static variable
Example ex = new Example(); ex.JustAme() //will work
System.out.println(a); –> wont work. System.out.println(ex.a); –> will work. }
public void JustAme(){ System.out.println(“OKay”); } }
Like static methods, we have static varialbes : **its value is the same for all the instances of the class.
Static varialbes have one value per class instances varialbes are one value per instance.
so, for eg to count the number of Duck classes created:
public class Duck{ private static int noOfDucks = 0; –>initialized only when the class is first loaded. not each time a new instance of the class is created. private int size;
public Duck{ noOfDucks++; }
public int getSize(){ return size }
public void setSize(int b){ size = b; } }
the static variable lives in the class, not in the object. So, say 5 Duck objects will all share only one copy of the static noOfDucks variable. if it is updated, it is updated in all of them.
**OQ: where does the static variable live, on the heap, on the stack? where on the heap/stack? (in the object, in which functions stack frame)
**so, static varialbes are shared, all instances of the same class share a single copy of the static variables. they belong to the class, not to the individual objects. **to make a class such that only one instance of that class is created and anyone who wants to use that class will have to use that one isntance ? declare the constructor method of the class as static!
THAT would be wrong(wont compile). the constructor cannot be static because the constructos main job is to instatntiate the instance variables - if it cant access it, how will it do that?
all static variables are initialized (the first time the class is loaded) i.e. before any object of that class are created or before any static method of the class runs. the static methods can accept arguments,
**static final variables are constants. **constant variable names must be all in CAPS, good pratice that is
**the code that runs just after the class has completed loading is called static initializer. it can be used to initialize the static variables. HENCE, the STATIC METHODS CAN ACCESS STATIC VARIABLES public class Hello{ public static int a; static{ a=2; } }
you can also use final on instance variables, local variables, and method parameters. also on methods or classes to stop someone from overriding the method or making a subclass.
**ban anyone from making a subclass of the present class (stop anyone from extending the class) - final [or constructor as private but the no one will be able to instatntiate the class as well] make sure you extend the class before using it – abstract make sure the method is overriden - abstract make sure all methods of a class are overriden - interface make sure the method is never overriden - final make sure the class is never instantiated - constructor private
void doStuff(final int x){ //now, x cannot change in the method body }
**if a varialbe is decalred final, its value wont change once it is assigned. so, you need to initialize the final variables, you cannot go with out initializing them. so, this wont work class Collar{ final int x;
public void go(){ System.out.println(x); } }
but, if it were int x; if would have printed 0.
- So, recall that the static methods cant use instance variables.
but this is different and legal :
public class Hello{
int x = 6;
public static void go(int x){ System.out.println(x); –> this is legal. } go(x); –> this isnt }
This is legal because the x we are giving to the static variable is its local variable. we arent touching the instance variable. if we wish to refer to the instance variable x, we can use this.x - however using it (for eg, printing it) will result in an error - because we are in the static method there.
if we wish to access the non static methods of the class from the static main method, we can create an object of the class and then use the object to call the methods. eg Dog d = new Dog(); d.bark(); this can be done in the static main of the dog class. THis cant: this.bark(); - this would have worked if the method wasn’t static.
- overloaded static methods are allowed - eg Math.round() is overloaded - it returns an int for an int etc.
- sometimes you want to wrap a primitive like an object.
before java 5, collection objects like ArrayList and HashMaps didnt take primitives. so, int x = 5; ArrayList a = new ArrayList();//generic ArrayList, this takes in anything and returns Object object
a.add(x); ==>wont work before java5. in java5, the primitive is wrapped as an object.
**what can the ArrayList store when we dont give it any specific type. like in ArrayList a = new ArrayList(); ANSWER ABOVE
- theres a wrapper for each primitive type in java - and the wrapper is in java.lang - so it doesnt need to be imported.
boolean - Boolean - be be char - Char - careful careful byte - Byte - bears because short - Short - shouldn’t sakru int - Integer - ingest is long - Long - large large float - Float - furry fucking double - Double - dogs dick
so : int i = 24; Integer i_wrapped = new Integer(i); –>wrapping int unWrapped = i_wrapped.intValue(); –> unwrapping
EARLIER : int a = 5; ArrayList b = new ArrayList(); b.add(new Integer(a)); Integer int_obj = (Integer) b.get(0); –> THIS IS BECAUSE THE OUTPUT IS A GENERIC OBJECT AND NEEDS TO BE TYPECASTed int got_int = int_obj.getInt();
NOW, with the autoboxing feature : ArrayList<Integer> a = new ArrayList<Integer>; a.add(4); —> the compiler automatically does the boxing and unboxing automatically. int b = a.get(0);
notice the type is Integer and not int - it needs object types only, not primitives.
autoboxing can be used anywhere to enable you to use a primitive or its wrapper type everywhere one is expected - automatically. so, an argument returns int ? you can make it return Integer. so, this is legal now :
public int go(){ return new Integer(4); }
here, in place of the int primitive, you are using a reference to the Integer wrapper (which isnt given any name here)
Also, this is legal : Integer i = new Integer(13); i++; int x = 4 Integer xx = new Integer(4) Double d = x; or Double d = xx;
What does autoboxing enable you to do? it enables you to use an reference to Integer wrapper where the primitive int was required and vice versa. for all the dataypes of java.
- **you can use static methods to create objects of the class iteself.
for eg, this is legal: class Test{ public static void main(String[] args){ Test t = new Test(); t.go() }
public void go(){ System.out.println(“HW”); }
- so, the wrappers allow us to use primitives where they earlier couldnt be allowed, great. but they are full fledged objects, they must have some useful utility methods too, right ? right.
wrappers have static utility methods (eg : Integer.parseInt(“4”));
94 ** “true” to true : boolean value_ = new Boolean(“true”).booleanValue();
turning a primitive into a string : int a = 4; String a_stringed = 4 + “”; or, also : String a_stringed = Integer.toString(a);
note, toString, is a static method of the Double, Integer etc wrapper classes.
- **THE + OPERATOR IS OVERLOADED IN JAVA, THE ONLY OVERLOADED OPERATOR.
- string formatting is taken care of in the java.util.Formatter class.
you can access the methods of this class using the String.format method format : String.format(formatting instructions||_aka as the format string_, __value to be formatted_);
String s = String.format(“%, d”, 100000000); System.out.println(s);
**anytime you see the percentage sign (%) in a format string (the first argument of the String.format method), think of it as representating a variable and that variable is the other argument to the method. the rest of the characters in the format string describe the formatting instructions.
String.format(‘%.2f’, 4141.151) ‘%.2f’ means, on % i.e. (4141.151), display it acc to .2f (so, as 4141.15) ‘%,.2f’ –> enters commas after thousands place
f == float, d == decimal (like an int, cant take 32.32 as an argument). x == hexadecimal (format(‘%x’, 42) -> 2a) c == chat, (format(‘%c’, 42) –> *)
syntax for the format string :
%[argument number][flags][width][.precision]type; if u have more than one arguemnts eg , minimum width sets no of decimal places f, d, i etc
eg : format(‘%,2.3f’)
- java supports variable argument lists - varargs.
- for all calender / time / dates etc related functionality, use the java.util.Calender class.
the class is abstract, so you cannot instantiate it. you will have to use its concrete subclass which you use a static method of the Calender class to get.
so, Calender cal = new Calender(); is not allowed Calender cal = Calender.getInstance(); –> this will get you the concrete subclass of the Calender abstract class.
**OQ: what is the use of that^ ? what inspired the makers to do it this way?
99.**INTERFACES CAN HAVE ONLY PUBLIC STATIC FINAL or GLOBAL CONSTANTS for variables. static because the interfaces can never be instantitated (abstract classes also cant be instantitated, and if any class has even one abstract method, it has to be marked abstract), so only static variabels can be used. Also, since they are static, they will be shared by all the instances of the objects which implement this interface - so, it is decalred final to avoid that. public so that you can access it.
- before java 8, you couldnt define static methods in an interface. so, this was illegal:
public interface Foo{ public static int bar(); –> this is illegal in java8 too }
but, this is allowed in java 8 public interface Foo{ public static int bar(){ //code } }
- **static methods are like classmethods in Python. you can use them without creating instances of the class, they belong to the class, all objects share it - everything matches !
- **why cant static methods be abstract in java ?
Regular methods can be abstract when they are meant to be overridden by subclasses and provided with functionality. Imagine the class `Foo` is extended by `Bar1, Bar2, Bar3` etc. So, each will have their own version of the abstract class according to their needs.
Now, static methods by definition belong to the class, they have nothing to do with the objects of the class or the objects of its subclasses. They don’t even need them to exist, they can be used without instantiating the classes. Hence, they need to be ready-to-go and cannot depend on the subclasses to add functionality to them.
Also, static methods cant be overriden (recall they CAN be overloaded). this is because, they belong to the class. the inheriting class can have its own static method of the same name, and when the static method is called using the name of the parent class, the overriden version wont be called, the old version, belonging to the parent class will be called. However, if the child doesnt have the static method defined, it can use its classname to call the parents static method
”” class Two { public static void main(String[] args){ Three t = new Three(); Three.staticMethod(); //prints “this is a static method of Three” One.staticMethod(); //prints the same message as above. if we uncomment the static method defined in One, we’ll get that executed. } }
class One extends Three{ // public static void staticMethod(){ // System.out.println(“this is the Overriden static method in one”); // } }
class Three{ public static void staticMethod(){ System.out.println(“this is a static method of Three”); } } “”
- Note there is a difference between abstract method and an empty method (a method that does nothing)
public abstract int foo(); - abstract public void foo(){} - empty method
- in System.out.println - out is a static variable of the System class.
- so, a class A extends B. both classes A and B have static initializtion print code, and also the constructor prints sometext too.
SEE THE QUESTION ON PG 310 - PLEASE - HEAD FIRST JAVA the order of the print statements will be : B’s static initializtion print lines. A’s static initializtion print lines. print code in A’s main() <<now, new A object is created - A a = new A();>> B’s constructor print lines A’s constructor print lines
Hence, when you have A extending B, and you create a object of A, the static initializtion of B runs, then static initializtion of A runs, then the constructor of B runs, then the constructor of A runs to get the object A ready.
- it is not good pratice to call a static method using the reference variable. eg :
Math.abs(-3); is good Math m = new Math();//this is not allowed because Math has its constructor marked as private. but, this rule appies else where where the constructor is not marked private and the class has static methods m.abs(-3); is not
- int has a default value of 0
Integer a; –> this a reference variable of type Integer will have default value of null because it points to no Integer object yet.
- you cannot mark a constructor as static.
constructors need access to the instance variables (to maybe give them a default value), static method cannot have that access, so static constructor doesnt make sense.
- constructor cannot be marked as final
this is because constructors are not inherited by the subclasses, so they cannot be overriden (things which arent inherited cannot be overriden) - so they are implicitly final. to avoid redundant keywords which only add confusion and not have any impact on the code, constructors arent allowed to have the final keyword.
- you can have more than one static initializtion blocks - all of them will be executed when the class is loaded and the constructor is called for creating the new object. they are executed in the sequence in which they appear.
- To emulate a static class :
set it to final – no one extends it now set constructor to private – no one initializtes it now set all methods to static - to get the static behaviour.
- in python : try, except
in java, try, catch An exception is an object, of type Exception you catch an Exception - catch(Exception ex)
Exception heirarchy : Throwable <– Exception <–IOException/InterruptedException Methods in Throwable inherited by Exception - getMessage(), printStackTrace();
Exceptions are thrown by methods when they fail. when your code could throw an Exception, you must declare the Exception. So, : say you have a method that can throw an Exception: public void takeRisk() throws BadException{ if (abandonAllHope){ throw new BadException(); –> create a new BadException object and throw it. } }
- compiler checks that you are handling the exceptions nicely - i.e. if your method throws and exception, you are declaring in the method defination and that all your trys also have catches etc.
except runtimeExceptions - the compiler wont complain if you dont catch them and all - IF IT DID, IT WOULD BE AWESOME ! YOU WOULD BE 100% THAT CODE THAT COMPILES WOULD BE THE CODE THAT RUNS eg : NullPointerException, ClassCastException these mainly come from a flaw in the logic in your code
**a try/catch is for handling exceptional situations(like the server not working) and not flaws in your code
so, runtimeExceptions are “unchecked exceptions” and all the others are “checked exceptions”
- static methods can be called without creating instances of the class - look at how it works in code :
public class One{ public static void main(String[] args){
One one = new One(); one.regularMethod(); ->works staticMethod(); –> works regularMethod(); –> doesnt work one.staticMethod(); –> works, not recommended to call static methods this way. One.staticMethod(); –> works, recommended
}
public void regularMethod(){ System.out.println(“Works!”); }
public statuc void staticMethod(){ System.out.println(“Works, the static one too!”); }
}
- the clause “finally” is used to write the cleanup code that you wish to execute regardless of exception thrown or not.
- A method can throw multiple exceptions and the catch can catch one or more
public void methodOne() throws Exp1, Exp2, Exp3{ //code }
try { riskyMethod(); } catch (Exception e){ //e.printStackTract(); }
You can say throws Exception { –> this is allowed because of polymorphism. children can take the place of their parents. so, where Exception object is expected, all its children can also be passed. //code }
- one try can have many catches the catches must be ideally be ordered from the most specific to most general
- you cannot put abstract catch statements before the specific ones.
- ducking an exception
when a method throws an exception, that method is popped off the stack and the exception is thrown to the next method on the stack - the caller. if the caller also ducks - it too is thrown off the stack and the exception is passed on to the next method.
you can duck an exception by declaring that the method throws that exception. so : public void foo() throws ClothingException{ //this is foo here, ducking the said exception
}
- so, two ways to handle the exception :
try / catch - write what to do in case it fails duck it - make a method duck it, it is then handled by the next method on the stack.
if you duck all the way till main() - the exception is just ignored. and the program compiles just fine.
**when you say a method throws an exception, it means that the method MAY throw that exception. it is not that it has to every time it runs. also, you dont have to import runtimeExceptions to use them in any method defination.
- **a try must be followed by a catch OR a finally.
a try with only a finally (and no catch) must declare the exception - i.e. the method having the try/finally must –> this makes sense because you arent solving the exception causing problem here, you are just catching it.
void go() throws NullPointerException{ try{ x.doStuff(); } finally{ //cleanup } }
- inner class - the nested class must be define inside the outer classes’s curly braces.
the inner class can access ALL the methods and instance variables of the outer class, even if they are marked as private. an inner class instance is tied to an outer class instance on the heap. steps to creating and using them :
- make an instance of outer class
- make an instance of inner class USING the outer class.
However, the inner class object doesnt not have to be linked to outer class object if the inner class is defined as static, then it can be created directly by using the class.
class MyOuter{ private int x; MyInner inner = new MyInner();
public void doStuff(){ inner.go(); }
class MyInner{ void go(){ x = 32; }}}
”” THIS IS WRONG! **You can initiate an inner class from outside the class if the inner class’s constructor is marked as static - this making the constructor a class method. so : class Foo{ public static void main(String[] args){ MyOuterClass outer = new MyOuterClass(); MyOuterClass.MyInnerClass inner = outer.new MyInnerClass();
This is because, we arent allowed to mark the constructor as static, even of the inner class. the constructor has a purpose - it has to initialize the instance variables of the innterclass. if it is marked as static, it wont be able to access them and they wont be initialized. “”
- Inner classes can be of use when you an seperate class but still want that class to behave as if it were part of another class.
}
}
- multithreading - when you want to run two loops at a time, use threading
**a new thread simply means a new seperate stack Create a new thread by creating an Thread object Thread t = new Thread(); t.start();
Thread class belongs to the java.lang package
- names of classes and interfaces are written in capital letters in java.
- the jvm starts multiple threads when it runs the code. there is a main thread - the one with the main() method at the bottom of it, there is a thread for garbage collection, and some other threads.
some important methods fo the Thread class - void join() - joins two threads void start() –> starts a thread static void sleep() –> gets a thread to sleep
- to make a new thread, make a runnable object (the threads job)
Runnable threadJob = new Runnable(); Runnable is an Interface you make a class implement that interface and that class will contain the work to be done by the new thread.
SO: runnable object has the work. thread object is the worker so, 3 steps : Runnable work = new YourRunnable(); Thread t = new Thread(work); -> this tells the new thread object which method to put at the bottom of the threads stack - work’s run() method t.start()
- the Runnable interface has just one method - the run() method
**see how the interfaces were used here to make sure that the work given to the thread compulsarily has a run() method which is then put at the bottom of the new stack.
- example usage of threads
class One{ public static void main(String[] args){ Runnable rbl = new MyRunnable(); Thread th = new Thread(rbl); th.start();
} }
class MyRunnable implements Runnable{ public void run(){ go(); }
public void go(){ doMore(); }
public void doMore(){ System.out.println(“Top of the new stack”); } }
How, the stacks work out: MAIN STACK main() -> th.start(); run(); –> this is the new stack, the main thread is now frozen go(); doMore(); go(); run(); th.starts(); main(); JVM shuts down
- the threads have three states :
Thread t = new Thread(r); —> a new thread object created, not startedyet - RED LIGHT t.start(); –> this thread is runnable once the JVM allows it to go - YELLOW LIGHT Running ! –> the jvm is green for this thread and it is running its methods in its stack - GREEN LIGHT
Threads can also be “blocked” even when it is in the runnable state - i.e. it is ready to go but the jvm is not allowing it to run –> ORANGE LIGHT
a thread can go between running to runnable
- the thread scheduler controls the threads. you cannot directly control it.
to make a thread go from running to runnable, make it sleep. this will get it off the jvms green light and it wont be back atleast until the the sleep-time is over again.
- **another way to start threads - subclass Thread, override its run method. that way you can use Threads no arg constructor and make a thread.
BUT this is not a great idea, heres why.
OO says that you should only subclass a class (i.e. extend the class) if you want to extend its functionality or make it ore specific.SO, we should only subclass/extend the Thread class if we wish to make a specific type of thread, tweak its behaviour etc. We want to write a new job for the thread - THAT and A SPECIFIC TYPE of thread are different things.
- once a thread completes its run() method, it is done for. it can never reused/restarted. it still could live on the heap and you can call other methods on it if approriate - but it cannot be resused.
- Ours is a quad core processor so, we can have 4 threads running in parallel.
- the sleep method of the Thread class is static, also it needs to be wrapped in a try catch because it can throw a checked exception (**checked exception means that the compiler checks that it is being handled properly (by try/catch or ducked) before allowing the code to compile)
So, do this to put a thread to sleep :
class MyThreadJob implements Runnable{ public void run(){ go(); }
public void go(){ try{ Thread.sleep(2000); } catch (InterruptedException ex){ ex.printStackTrace(); } } doMore();
public void doMore(){ System.out.println(“The job of thread is hereby completed”); } }
class Example{ public static void main(String[] args){ Runnable work = new MyThreadJob(); Thread th = new Thread(work); th.start();
System.out.println(“This should come before the other thread”); } }
- **the problem with multiple parent classses for a child class was that if both the parents had a method a() implemented, and it was called on the child classes’ object, which one should it call ? Hence, we have interfaces. they have abstract methods - whihc the child MUST override. hence, when those methods are called on the child classes object, the overriden method is called - no problems there.
Is it possible to have an interface have a abstract method a() and also the child class’s parent have that method ? it has no utility - because this would mean that the child HAS to override that method. now, if you just wanted to make sure that the child overrides the method, why not declare it abstract in the class itself. (this would make the parent class abstract too, and wouldnt allow anyone to instantiate it without extending it first)
”” **OQ: wont this^ be unconvient? say, I have this class that does many things. it has a lot of methods and a lot of functionality that is ready to be used. however, there is this one feature that needs some more generalization before it can be used. I mark that particular method as abstract. but this will ruin my entire class, it wont be usuable out of the box, it will have to be implemented, even for the features that worked fine out of the box earlier. “”
- so if a class implements an interface, it MUST implement all its methods. that is unless you decalre the class as abstract ! So, if an abstract class implements an interface, it can get away without implementing some of the interfaces mmethods and the class which subclasses the abstract class has to implement them.
- give the threads names - thread.setName(“Alpha thread”);
- java collections have all the data structures that “you will ever need!”
- ArrayList is ordered - just like list.
- how to read a file line by line :
import java.util.*; import java.io.*;
public class One{
ArrayList<String> songList = new ArrayList<String>(); //songlist is an instance variable, accessible to all the methods of the class
public static void main(String[] args){ new JukeBox().go(); //this is a cool way to make objects on the heap and not assign reference variables to pointing to them }
public void go() { getSongs(); System.out.println(songList); }
public void getSongs() { try{ File file = new File(“SongsList.txt”); BufferReader reader = new BufferReader(new FileReader(file)); String line = null; while ((line = reader.nextLine()) != null) { addSong(line); //non static methods can access other non static methods }} catch (Exception ex) { ex.printStackTrace(); }
public void addSong(String linetoParse) { String[] tokens = linetoParse.split(“/”); songList.add(tokens[0]); } } } }
- ArrayList does not sort.
TreeSet - keeps elements sorted and prevents duplicates HashMap - sort and access elements as name value pairs - dict LinkedHashMap - remembers the order in which elements were inserted - ordereddict LinkedList - better performance when deleting and inserting from middle of collection HashSet - prevents duplicates, fast search and retrieval
- java.util.Collections class
has a sort method - it takes a list, (ArrayList implemets an List interface, so Collections can sort ArrayList too) it sorts in place, it doesnt return the new sorted array. So, it is as simple as : Collections.sort(songList); –> it is sorted now.
- every object when printed has toString() called on it. It is in the Object class - so everyclass has the method somewhere in its inheritence tree. you can override it thus:
public String toString() { return “Whats up”; }
So, this prints “Whats up!” class Example{ public static void main(String[] args) { System.out.println(new Example()); }
public String toString() { return “Whats up!”; }
}
- generics means more type safety.
recall type safety is the gurantee that you cannot put a Dog in a Cat object reference variable. **good if the problems are caught at compile time rather then the runtime.
They allow “a type or method to operate on objects of various types while providing compile-time type safety.”
You need a single “sort” method that would sort numbers, strings etc. Generics allow you to do that. Generic methods allow the user to create with a single method declaration, a set of realted methods and generic classes allow the user to with a single class declaration, create a set of realted classes.
so, you can write one generic function for sorting and it would sort arrays, lists, numbers, strings etc. all generic methods declarations have a type parameter section delimited by angle brackets. that precede the methods return type.
collections are “virtually” the only ones of the entire java api that needs generic classes - because they have the general methods like sort etc. generic classes are essentially classes that can hold a variety of other classes and expect the user to specify what they will be holding when they declare and instantiate them
- In the java api docs - the collections package’s classes will have E - this is stand-in for the type of element you want the collection to hold and return - so, in ArrayList<Dog> dog = new ArrayList<Dog>(); , the E (Element) is Dog.
it is written in the docs like this:
class ArrayList<E> extends AbstractList<E> implements List<E> … { public boolean add(E o) –> here, E can become Dog, String, int/Integer etc //code }
E is the convention, you can use anything else too - but it is a convetion to use single capital letter.
- to declare the generic type paremeter for just the method,
public <T extends Animal> void takeThing(ArrayList<T> list) { //code } – here it means that T can be of any type of animal i.e. Dogs, Cats
public void takeThing(ArrayList<Animal> animal){ –> just takes in the Animal type //code }
you might be wondering why cant you just accept Animal type and then, automatically, you would be able to accepts Dogs, Cats etc
Because, in regular Java, this was perfectly legal
class Animal{ public makeNoise(){ //code } }
class Dog extends Animal{ public makeNoise(){ //code }
public sitDown(){ //code } }
class Example{ public static void main(String[] args){ Animal an_animal = new Dog(); –> legal ! takeIn(Dog); –> this is legal ! }
public static void takeIn(Animal a){ System.out.println(“Just took an animal”); } } –> this is put to rest because we wont need to compare objects anytime soon.
- **javac invokes the compiler
java invokes the jvm. so, compile using the compiler and give the byte code to the jvm using java <class_name>
- list is useful when the sequence matters, it is ordered
set is useful when uniqueness matters, it is unordered So, sets cannot have more than one element referencing the same object map - when you need a dict - no duplicate keys allowed
- Collections API :
Collection –> Set and List Set –> SortedSet( –> TreeSet), LinkedHashSet, HashSet List –> ArrayList, LinkedList, Vector
Map –> SortedMap (–> TreeMap), HashMap, LinkedHashMap, Hashtable
- Using hashset (prevents duplicates, fast retrieval and search)
HashSet<Dog> dog = new HashSet<Dog>(); ArrayList<Dog> songList = new ArrayList<Dog>(); dog.addAll(songList)
**what is the diff b/w hashtable and hashset?
- a static inner class cannot refer to the non static (instance) variables and methods of the outer class.
Remember you cannot go to any method of the class (like go(); or doStuff();) from the main method. this is because main() is static and cannot refer to non static (regular) instance variables and methods - you can use them if you create a object of the class and then call them.
- **everything i know about static variables
they are initiated before the static method and can be used by the static methods. they belong to the class, and so are shared by ALL the obejct instances of the class. they can be used by non static methods, if declared “final”, then they need to be initialized, they dont get a default value, otherwise they do. interfaces can have only public static final variables.
- **everything I know about static methods
they belong to the class, they dont need the class to be initiated to be used, they can be used directly by ClassName.staticMethodName(), they can use the static varialbes of the class but not the regular methods or regular (instance) varialbes. it is bad pratice to call them like objectOfaClass.staticMethodName() - though it is legal. they are used if you need some method that doesnt need the instance varialbes and so for them to be used, creating an object is wasting space on the heap. also, static methods can call other static methods and static variables.
- Generally how it all is done is this way:
the entire file contains one big class - say LinkedList the class has several methods and instance varialbes. it may also have inner classes etc. those methods maybe used to add a new node, print out the DS etc.
at the end of the plethora of methods, there is the main() method. the main() method would create a object of the class and use it.
- Java’s null == Python’s None
- Say some one calls a method with wrong data, you can do this:
if (afterNode = null) { System.out.println(“Prev cant be null”); return; //the HIT }
- What does this line mean ? [erm, what?]
- I suggest wrongly that ArrayList has a LL implementation. It is not true, it is just a array that when it gets full, its size is doubled. doubling takes O(n) time. Access is O(1) time.
- static methods can also be looked upon as standalone methods, they are not some operation on an object(to be more specific, an object’s data).
- How to make inner classes and create them
class Four { int a; class Inner { Inner(int b) { a = b; } public void printa() { System.out.println(a); } }
Inner n = new Inner(2); //this is allowed, as this instance of Inner class is bound to the class object. – this is because it is created only when an object of Four is created. }
class Three { public static void main(String[] args) { Four f = new Four();
Four.Inner i = f.new Inner(2); ^ //note here, we identify the Inner class as Four.Inner. also, in the rhs, we cant use Four.new Inner(), this is because the Inner class instance needs to be bound to an instance of the outer Four class
i.printa(); } }
What if the inner class was static? it wouldnt be allowed to access the instance variables and methods of the outer class (and rightly so), but how would it be instantited?