Sharpen your tools if you want to do a good job!
Again fast can not fast foundation, again rotten can not rotten language!
Chapter 1 Introduction to objects
“The main reason we break down the natural world, organize it into concepts and categorize it according to their meanings, is that we are participants in an agreement shared by the whole society of spoken communication, which is fixed in language…… We cannot talk at all unless we endorse the organization and classification of linguistic information provided for in this agreement. — Benjamin Lee Whorf(1897~1941)”
1.1 Abstract Process
- Object-oriented features:
- Everything is an object. In addition to thinking of an object as a fancy variable that can store data, you can ask it to perform operations on itself. In theory, you can extract any conceptual construct of the problem to be solved (dog, building, service, etc.) and represent it as an object in the program.
- Programs are collections of objects that tell each other what to do by sending messages. To request an object, you must send a message to the object. More specifically, you can think of a message as a request to invoke a method on a particular object.
- Each object has its own store made up of other objects. In other words, objects of a new type can be created by creating packages containing existing objects. Thus, it is possible to build complex architecture in a program while hiding its complexity behind the simplicity of the object.
- Each object has its type. In common parlance, “every object is an instance of some class,” where “class” is a synonym for “type.” The most important feature that distinguishes each class from the others is what messages can be sent to it.
- All objects of a particular type can receive the same message. That’s a meaningful statement, as you’ll see in a moment. Because objects of the “round” type are also objects of the “geometry” type, a “round” object must be able to receive messages sent to “geometry” objects. This means that you can write code that interacts with “geometry” and automatically handles all transactions related to geometry properties. This substitutability is one of the most powerful concepts in OOP.
- Each object has a unique address in memory(Each object can be uniquely distinguished from other objects).
1.2 Every object has an interface
-
Creating abstract data types (classes) is one of the basic concepts of object-oriented programming.
Abstract data works almost exactly like built-in types: you can create variables of a certain type (called objects or instances in object-oriented terms) and then manipulate those variables (called send messages or requests; Send the message and the object knows what to do.
-
Each object belongs to a specific class that defines its properties and behavior.
-
Because a class describes a collection of objects with the same properties (data elements) and behavior (functionality), a class is really just a data type.
-
An interface identifies the requests that can be made to a particular object.
1.3 Each object provides services
-
High cohesion and low coupling
Cohesion: To measure the relationships within modules from a functional perspective, a good cohesive module should do exactly one thing. It describes the functional relationships within a module;
Coupling: A measure of the interconnections between modules in a software structure, depending on the complexity of the module’s indirect ports, the points that enter or access a module, and the data passing through the interfaces.
High cohesion and low coupling, a concept in software engineering, is a standard to judge the quality of design, mainly object oriented design, mainly depends on whether the class cohesion is high, coupling degree is low.
Coupling: also called interblock connection. A measure of how closely interrelated the modules of a software system are. The closer the connection between modules, the stronger the coupling, the worse the independence of modules. The level of coupling between modules depends on the complexity of module indirection, the way of invocation and the information transmitted
Cohesion: also known as intra-block connection. A measure of the functional strength of a module, i.e. how closely the elements within a module are integrated with each other. The more closely the elements of a module (language names, program segments) are related, the higher its cohesion is.
High cohesion refers to the fact that a software module is composed of highly related code responsible for only one task, which is often referred to as the principle of single responsibility.
Coupling: A measure of the degree of interconnection between different modules within a software structure.
For low coupling, the crude understanding is: a complete system, between modules, as far as possible to make it independent. That is to say, let each module, as much as possible, independently complete a specific sub-function. The interface between modules should be as few and simple as possible. If the relationship between two modules is complex, it is best to consider further module partitioning first. This facilitates modification and composition.
-
There is a side benefit to thinking of objects as service providers: it helps to improve the cohesion of objects. High cohesion is one of the basic quality requirements of software design: it means that aspects of a software construct (an object, for example, but it could also mean a method or a library of objects) are “assembled” well. One of the problems people face when designing objects is cramming too much functionality into one object.
-
In good object-oriented design, each object does a good job of doing one thing, but it doesn’t try to do more.
-
Regard object as a service provider is a great simplifying tool, this is very useful not only in the design process, and when others to understand your code or reuse an object, if they see the value of this object can provide service, it will make the adjustment object to its design process becomes much simpler.
1.4 Concrete implementation of hidden by shadow
- It is useful to divide programmer developers by role into class creators (those who create row data types) and client programmers (class consumers who use data types in their applications). The goal of the client programmer is to assemble a variety of classes for rapid application development. The goal of the class creator is to build classes that expose only the necessary parts to the client programmer and hide the rest.
- Reasons for the existence of access control
- The first reason for existence is to keep client programmers from touching parts they shouldn’t.
- The second reason for existence is to allow library designers to change the internal workings of classes without worrying about upsetting the client programmer.
- JAVA boundary value
- Public: indicates that the element immediately following it is available to anyone.
- Private: The keyword represents an element that is not accessible to anyone other than the type creator and the internal methods of the type. Private is like a brick wall between you and the client programmer, and if someone tries to access it they will get an error message at compile time.
- Protected: The protected keyword is the same as private, except that the inherited class can access protected members, but not private ones.
- Default access: This comes into play when none of the previously mentioned access designations are used. This permission is often referred to as package access because it allows classes to access members of other classes in the same package (library artifacts), but outside of the package, these members are specified as private.
1.5 Specific implementation of reuse
-
Code reuse is one of the greatest benefits that object-oriented programming language locks provide.
-
A new type can be composed of any number of other objects of any type in any way that implements the desired functionality of the new class.
-
Because you are using existing classes to compose new classes of other objects, this concept is called composition, and if composition occurs dynamically, it is often called aggregation.
-
When creating a new class, composition should be considered first because it is simpler and more flexible. If you take this approach, the design becomes clearer and, once you have some experience, you can see where inheritance must be used.
1.6 inheritance
-
When the source class (called a base class, superclass, or superclass) changes, the modified “copy” (called an derived class, inherited class, or subclass) also reflects the change.
-
A base class can be created to represent the core concepts of some objects in the system, and other types can be derived from the base type to represent the various ways in which this core can be implemented.
-
When you inherit an existing type, you create a new type. Not only does this new type include all the members of the current type (although the private members are hidden and not accessible), but more importantly it replicates the interface of the base class. That is, all messages that can be sent to the base object can also be sent to the exported object.
-
Type equivalence through inheritance is an important threshold to understanding the implications of object-oriented programming methods!
-
There are two ways to make a base class different from an derived class
-
- Add the new method directly to the exported class. These new methods are not part of the base class interface. This means that the base class does not meet all your needs, so more methods must be added.
-
- One way to make a difference between derived and primary classes is to change the behavior of methods of existing primary classes, a method known as overriding that.
-
-
Inheritance should only override the methods of the base class (and not add new methods that don’t exist in the base class), which is, in a sense, an ideal way to handle inheritance. We often refer to the relationship between the base class and the derived class in this case as IS-A.
-
Sometimes new interface elements must be added to the export type, thus extending the interface. This situation can be described as an IS-like -a relationship.
1.7 Interchangeable objects associated with polymorphism
-
The ability to easily extend your design by exporting new subtypes is one of the basic ways to encapsulate changes.
This capability can greatly improve our design while also reducing the cost of software maintenance.
-
The most important tip of object-oriented programming: the compiler cannot make function calls in the traditional sense. A function call produced by a compiler that is not object-oriented programming causes so-called pre-binding, a term you may not have heard of before and may not have thought about other ways of calling a function. Doing so means that the compiler generates a call to a specific function name, and the runtime resolves the call to the absolute address of the code to be executed. In OOP (object-oriented programming), however, the program cannot determine the address of the code until run time, so when a message is sent to a generic object, another mechanism must be employed.
-
When a message is sent to an object, the code being invoked is not determined until runtime. The compiler ensures the existence of the called method and performs type checks on the call parameters and return values (languages that do not provide such guarantees are said to be weakly typed), but does not know the exact code that will be executed.
-
In Java, dynamic binding is the default behavior, and no additional keywords need to be added to achieve polymorphism.
-
The process of treating the derived class as its base class is called upward transformation.
The name transformation is inspired by the action of model casting; The word up comes from the typical layout of inheritance diagrams; Usually the base class is at the top and the derived class is spread out below it. Thus, to transition to a base class is to move up in the inheritance diagram, or “transition up.”
-
It’s because of polymorphism that things always get done right. The compiler and the operating system take care of the details, and all you need to know right away is that things happen, and more importantly, how to design through it. When sending a message to an object, the object knows what the correct behavior is to perform, even if it involves an upward transition.
1.8 Single root inheritance structure
- In OOP, do all classes ultimately inherit from a single base class? The answer is yes, and the name of the ultimate base class is Object. As it turns out, the single-root inheritance structure provides many benefits.
- All objects in a single-root inheritance structure have a common interface, so they all boil down to the same basic type.
- The single-root inheritance structure guarantees that all objects have some functionality.
- The single-root inheritance structure makes it much easier to implement the garbage collector, which is one of Java’s major improvements over C++. Because all objects are guaranteed to have their type information, there is no deadlock because you cannot determine the type of the object. This is especially important for system-level operations, such as exception handling, and gives greater flexibility to programming.
1.9 Containers (Collections)
-
Containers (also known as collections, but Java libraries use the term “collections” in a different sense, so this book uses the word “container”) can expand themselves whenever needed to hold everything you put in them. So you don’t need to know how many objects you’ll put in the container, just create a container object and let it handle all the details.
-
Java container
- List(for storing sequences)
- Maps (also known as associative arrays, which are used to establish associations between objects)
- Set(holds only one for each object type)
- Lots of queues, trees, stacks and more.
-
Use containers selectively for the following reasons:
- Different containers provide different types of interfaces and external behaviors. A stack has a different interface and behavior than a queue, and a different interface and behavior than a collection list. Some of these containers may provide a much more flexible solution than others.
- Different containers have different efficiencies for certain operations. The best example is a comparison of two kinds of lists: ArrayList and LinkedList. They are all simple sequences with the same interface and external behavior, but the cost of certain operations is vastly different. In an ArrayList, randomly accessing elements is a fixed-time operation; However, for LinkedList, randomly selected elements need to be moved through the list, which is costly, and accessing elements closer to the end of the table takes longer. On the other hand, if you want to insert an element in the middle of a sequence, LinkedList is less expensive than ArrayList.
-
We can start with the LinkedList builder and switch to ArrayList when tuning system performance. The abstraction provided by the interface List minimizes the impact on code when converting between containers.
-
Parameterized Types (Generics) Before JavaSE5, objects stored in containers had only the generic Java type Object.
The single-root inheritance structure means that everything is of type Object, so containers that can store objects can store anything. This makes containers easy to reuse.
-
Upward transformation is safe. For example, Circle is a Shape type. But you don’t know whether an Object is a Circle or a Shape, so unless you know exactly what type of Object you’re dealing with, it’s almost unsafe to transition down.
-
If you cast down an error, you get a runtime error called an exception.
-
A parameterized type (a stereotype) is a class that the compiler can automatically customize for a particular type. For example, by using parameterized types, the compiler can customize a container that only accepts and retrieves Shape objects.
-
Many standard library builds have been modified to take advantage of generics. As we’ll see, generics have had an important impact on much of the code in this book.
1.10 Object creation and lifetime
-
One of the most critical issues when working with objects is how they are generated and destroyed.
Every object needs resources, especially memory, in order to survive. When we no longer need an object, it must be cleaned up. So that the resources it occupies can be released and reused.
-
For maximum execution speed, the storage space and life cycle of an object can be determined at program writing time.
-
This can be done by placing objects on the stack (they are sometimes referred to as automatic variables) or in scoped variables or static storage areas.
This approach prioritizes the allocation and release of storage space, and in some cases this control can be very valuable. However, flexibility is also sacrificed because you must know the exact number, lifecycle, and type of objects when writing your program.
-
The second way is to create objects dynamically in a pool of memory called a heap.
In this way, it is not known until run time how many objects are needed, what their life cycle is, and what their specific types are.
-
-
If a new object is needed, it can be created directly in the heap at the moment it is needed. Because storage is managed dynamically at run time, it takes a lot of time to allocate storage in the heap, which can be much longer than it takes to create storage in the stack.
-
The time taken to create stack storage depends on the design of the storage mechanism
-
A general logical assumption for dynamic approaches is that objects tend to become complex. So the overhead of finding and freeing storage space does not have a significant impact on object creation. The greater flexibility afforded by dynamic approaches is the point of solving general programming problems.
-
Java is all about dynamic memory allocation. Whenever you want to create a new object, you use the new keyword to build a dynamic instance of that object.
-
And then there’s the life cycle. For languages that allow objects to be created on the stack, the compiler can determine how long the object is alive and can destroy it automatically.
-
Java provides a mechanism called a “garbage collector” that automatically detects when an object is no longer in use and destroys it.
The garbage collector is very useful because it reduces the issues you have to consider and the code you have to write. More importantly, the garbage collector provides a higher level of assurance against potential memory leaks.
-
Java’s garbage collector is designed to deal with memory release issues (although it does not cover cleaning up other aspects of objects). The garbage collector “knows” when an object is no longer in use and automatically frees its memory.
1.11 Exception Handling: Handling errors
- An exception is an object that is “thrown” from the point of failure and “caught” by the appropriate exception handler specifically designed to handle a particular type of error. Exception handling is like an alternative path that runs parallel to the normal execution path of the program when an error occurs. Because it is a completely separate execution path, it does not interfere with normal execution code.
- A thrown exception cannot be ignored, unlike the error value returned by a method or the flag bits set by the method to indicate the error condition, so it is guaranteed to be handled somewhere.
- Exceptions provide a way to reliably recover from an error condition. Instead of just quitting the program, you can make frequent corrections and resume the program, which helps you write more robust programs.
1.12 Concurrent programming
- One of the basic concepts in computer programming is the idea of juggling multiple tasks at the same time.
- The parts of a program that run independently of each other are called threads.
- For a large number of problems, improve the responsiveness of the program by dividing the problem into independently running parts (tasks). Call it concurrency.
- Threads are simply a means of allocating execution time to a single processor.
- If you have multiple parallel tasks accessing the same resource, you can have a problem. For example, two processes cannot send messages to a printer at the same time. To solve this problem, resources that can be shared, such as printers, must be locked for the duration of use. Thus, the whole process is as follows: a task locks a resource, completes its task, and then releases the resource lock so that other tasks can use the resource.
Chapter 2 Everything is an object
“If we spoke a different language, we would find a slightly different world. – Luduing Wittgerstein (1889 ~ 1951)”
2.1 Manipulating objects with references
-
In Java, everything is treated as an object, so a single syntax can be adopted. Although everything is thought of as an object, the identifier for an operation is actually a “reference” to the object.
Example: The remote control (quote) operates the TELEVISION (object).
- An identifier for a Java operation is actually a “reference” to an object
- An identifier for a Java operation is actually a “reference” to an object
- An identifier for a Java operation is actually a “reference” to an object
2.2 You must create all objects
- The new keyword means “give me a new object”.
- Where data is stored:
-
Registers: The fastest storage area, but because the number of registers is extremely limited, they are allocated on demand. You can’t control it directly, and you can’t feel any sign of registers in the program.
-
Stack: Located in universal RAM(Random access memory). Moving the stack pointer down allocates new memory, moving it up frees memory.
STACK: STACK. In fact, there is only one entry and exit queue, that is, First In Last Out (First In Last Out), the First allocated memory must be freed later. Generally by the system automatically allocated, stored function parameter values, local variables, etc., automatically cleared.
The stack is broken up as each function enters and released as the function returns
Local variables are put on the stack, so the function returns, and the local variables are gone.
-
Heap: A generic memory pool (located in the RAM area) that holds all Java objects.
When you need an object, you write a simple line of code with new, and when you execute this line of code, it automatically allocates storage in the heap.
Allocating and cleaning up storage with the heap can take more time than allocating storage with the stack.
-
Constant storage: Constant values are usually stored directly inside program code.
-
Non-ram storage: If data exists completely outside the program, it can exist without any control from the program, even when the program is not running. For example: stream objects and persistent objects.
-
- Basic data types
- Instead of creating an object with new, basic datatypes create an “automatic” variable that is not a reference. This variable stores “values” directly and is placed on the stack, so it is more efficient.
- All data types are signed, and there are no unsigned numeric types.
- A wrapper class for a primitive type that allows you to create a non-primitive object in the heap that represents the corresponding and this type.
- Java SE5’s autowrap feature automatically converts the base data types to wrapper types.
- Java provides two classes for high-precision calculations: BigInteger (which supports integers with arbitrary precision) and BigDecimal (which supports fixed-point numbers with any precision).
2.3 Objects should never be destroyed
- scope
- The scope is determined by the position of the curly braces.
- Variables defined in a scope can only be used until the scope ends.
- Object scope
- When new creates a Java object, it can live out of scope.
- Java has a garbage collector that monitors all objects created with New and identifies those that are no longer referenced. Later, the memory space of these objects is freed up for use by other new objects.
2.4 Creating a new data type: class
- The class keyword is followed by the name of the new type.
- All you do in Java is define classes, generate objects of those classes, and send messages to those objects.
- A field can be any type that can be communicated with by reference, or one of the basic types.
- If the field is a reference to an object, the reference must be initialized so that it is associated with an actual object.
2.5 Methods, Parameters, and Return Values
- Java’s methods determine what messages an object can receive, and the composition (name, parameter, return value, method).
- Method names and parameter lists uniquely identify a method.
- The act of calling a method is often referred to as sending a message to an object.
- Object-oriented programming is often summed up simply as “sending messages to objects.”
- Often, even though you are passing an object, you are actually passing a reference to it.
2.6 Building a Java Program
- Java uses domain names to ensure that each class is unique.
- The static keyword
- When new is executed to create an object, data storage space is allocated and its methods are available for external calls.
- New Creates two scenarios in which objects cannot be created:
-
- You just want to allocate a single storage space for a particular domain, regardless of how many objects you want to create, or even none at all.
-
- You want a method not to be associated with any object that contains its class. This means that you can call this method without creating an object.
- When a thing is declared static, it means that the field or method is not associated with any object instances of the containing class.
-
- You do not need to create any objects before using the static method (or domain).
- A static field has only one storage space per class, whereas a non-static field has one storage space per object
Chapter 3 operators
3.7 Relational operators
- == and! = compares references to objects.
- If you want to compare whether two objects are actually the same, you must use equals(), which applies to all objects.
- Basic types use == and! =
Chapter 4 Control execution process
- Java does not allow us to use a number as a Boolean!
- The return keyword has two uses:
- One is to specify what value a method returns
- On the other hand it causes the current method to exit and return that value.
- Break is used to force out of the loop without executing the remaining statements in the loop.
- Continue stops execution of the current iteration and then goes back to the beginning of the loop to start the next iteration.
Chapter 5 Initialization and cleanup
5.1 Ensure initialization with constructors
- The constructor has the same name as the class, and when the object is created, new XXX() will allocate storage for the object and invoke the corresponding constructor. This ensures that the object is initialized before it can be manipulated.
- Each class has a default constructor, called a “no-parameter constructor” in the Java documentation.
- A constructor is a special type of method that returns no value.
- In Java, “initialization” and “create” are tied together, and the two cannot be separated!
5.2 Method Overload
- Overloading: same method name but different formal parameters.
- Each overloaded method must have a unique list of parameter types.
- Overloaded methods cannot be distinguished by their return value.
- The most common use of overloading is constructor reloading!
5.3 Default constructor
- The default constructor (aka the “no arguments” constructor) has no formal parameters — it creates a “default object.”
- If there is no constructor in the class, the compiler will automatically create a default constructor for you. But if you have already written a constructor (with arguments), the default constructor will be overwritten (that is, there is no default constructor in the class (no arguments), and if you need a no-argument constructor you need to add one yourself).
5.4 This keyword
class Banana { void peel(int i) {/*...*/} }
public class BananaPeel{
public static void main(String[] args) {
Banana a = new Banana();
Banana b = new Banana();
a.peel(1);
b.peel(2);
}
}
Copy the code
Question: How does Peel () know whether it was called by A or B?
[A] : The compiler implicitly passes "operation object reference" as the first argument to Peel (), a.eel (a,1); This is the internal representation.Copy the code
- If you need a reference to the current object inside a method, use the this keyword!
- The this keyword can only be called inside a method!
- When this is written, it usually means “this object” or “current object” and itself refers to a reference to the current object.
- You can call one constructor with this, but you can’t call two, and the constructor must be at the beginning or an error will be reported.
- The compiler forbids calling constructors in any method other than constructors!
- Static means there is no this method
- Non-static methods cannot be called from the inside of static methods
- Static can call static methods from the class itself without creating an object.
5.5 Cleanup: End disposal and garbage collection
-
The garbage collector in Java is responsible for reclaiming memory resources occupied by unwanted objects.
-
The garbage collector only knows to free the memory allocated by new.
-
Finalize () : A method called before the garbage collector is ready to release the storage space occupied by reclaimed objects, which can be customized to do some cleanup.
The difference between Finalize () and destructor:
Destructors (you must use this function to destroy objects in C++) : destructors, as opposed to constructors, are automatically executed when an object ends its life cycle, such as when the function in which the object was created has been called. Destructors are often used to clean up the mess.Copy the code
-
Java objects are not always garbage collected:
- Objects may not be garbage collected.
- Garbage collection is not “destructor.”
- Garbage collection is only about memory.
-
In Java, as long as the program is not on the verge of running out of storage, the space occupied by objects is never released.
-
The only reason to use a garbage collector is to reclaim memory that your program no longer uses.
-
Use of Finalize () — To free up space:
- Regardless of how the object is created, the garbage collector is responsible for freeing any memory the object occupies.
When “local methods” are used in code, such as calling C’s malloc() function family to allocate storage space, we need to call free() in Finalize to free memory space.
Note: A native method is a method that calls non-Java code in Java, usually with the “native” keyword.
-
Use of Finalize () — Final condition verification:
To validate some state of an object before its resources are released, putting the validation content ina finalize() method can avoid some defects caused by code writing problems.
Note: Finalize methods are unpredictable, dangerous, and generally unnecessary, as mentioned in the section “Avoid Finalizing methods and Clear Methods” in Effective Java. Using finalizing methods can lead to erratic behavior, performance degradation, and portability issues, and should be avoided as a rule of thumb.
-
How does the garbage collector work
Allocating objects on the heap is expensive, and so is the way all objects are allocated in Java. The garbage collector, however, has the obvious effect of speeding up object creation.
- In some Java virtual machines, the heap is implemented like a conveyor belt, moving one space forward for each allocated object, which means that the allocation of object storage is very fast.
- The Java heap doesn’t exactly work like a conveyor belt.
- When it works, it reclaims space and compacts objects in the heap so that the heap pointer can be easily moved closer to the beginning of the conveyor belt, avoiding incoming page errors. Through the garbage collector to rewrite the arrangement of objects, a high-speed heap model with infinite space to allocate is implemented.
-
Implementation of garbage collector:
The garbage collector is based on the idea that any “live” object must eventually be traced back to references that exist on the stack or in static storage.
-
Reference counters: a simple but slow garbage collection technique.
Each object contains a reference counter, which is incremented by one when a reference is connected to the object. When a reference leaves scope or is set to NULL, the reference counter is reduced by 1. The garbage collector facilitates a list of all objects, and when it finds an object with a zero reference count, it frees the space it occupies. But circular references result in “objects that should be recycled, but count is not zero.”
Reference counting is not used in any Java virtual machine implementation.
-
To stop or copy:
The program is paused (not in background recycle mode), and then all surviving objects are copied from the current heap to another heap. Anything that is not copied is garbage. When an object is moved from one place to another, all references to it must be corrected. References that reside in the heap or in static storage can be modified directly, but there are other references to point to that can only be found during traversal.
This way, it’s inefficient. On the one hand, you need to bounce back and forth between two separate stacks; On the other hand, once the program is stable, it may produce little or no garbage, but still copy all of its memory from one place to another.
Garbage collection does not take place in the background, and the program is paused while garbage collection takes place.
“Stop-copy” requires that all surviving objects must be copied from the old heap to the new heap before the old objects can be released. This results in a lot of memory replication.
-
Mark, sweep
Starting from the stack and the static store, traverse all references to find all surviving objects. Whenever a viable object is found, a tag is assigned to the object, but no object is reclaimed. Clean up only when all marking is complete. Untagged will be released, and tagged will be copied. The program must be paused before proceeding.
-
“Adaptive, generational, stop-copy, mark-sweep” garbage collector
- Memory allocation is measured in larger “blocks”, and if the object is large, it occupies separate blocks. With blocks, the garbage collector can copy objects into the discarded block at collection time.
- Each block has a corresponding algebra (generation count) to record whether it is still alive.
- If a block is referenced somewhere, its algebra increases, and the garbage collector collates newly allocated blocks since the last collection action (great for dealing with a large number of short-lived temporary objects).
- The garbage collector does a full cleanup on a regular basis – large objects are still not copied (only their algebra increases), and those containing small objects are quickly copied and collated.
- The Java virtual machine monitors and switches to mark-sweep if all objects are stable and the garbage collector becomes less efficient.
- The Java virtual machine tracks the effect of mark-sweep and switches to stop-copy if there is a lot of fragmentation in the heap. Switching between different ways for different situations is called “adaptive” technology.
-
5.7 Constructor initialization
-
A variable in a class is initialized before the constructor
-
Static data occupies only one storage area, no matter how many objects are created.
-
The static key cannot be applied to local variables, only to fields.
-
If it is a static primitive type field and is not initialized, it gets the standard initial value for the primitive type.
If it is an object reference, its default initial value is NULL.
-
Static storage initialization time:
Static members of a class are loaded as the class is loaded, either when an object is created or when it is referenced!
Static members of a class are loaded as the class is loaded, either when an object is created or when it is referenced!
Static members of a class are loaded as the class is loaded, either when an object is created or when it is referenced!
-
The order of initialization is first for static objects, then for “non-static” objects.
-
Object creation process
- When static methods are not explicitly used, the constructor is actually static. When an object is created or the class’s static methods/static fields are first accessed, the Java interpreter finds the classpath and then locates the.class file.
- Load the.class file, and all the actions related to static initialization are performed. Therefore, the static initial file is only done once when the Class object is first loaded.
- When created using new(), enough space is allocated on the heap for the object.
- The storage space is zeroed out, all base data is set to default values, and references are set to NULL.
- Performs all initialization actions that occur at the field definition.
- Execute the constructor.
5.10 summarize
- Constructors guarantee proper initialization and cleanup (the compiler won’t allow objects to be created without proper constructor calls), so you have complete control and security.
- The garbage collector automatically frees memory for objects, so in many cases, similar cleanup methods are not needed in Java.
- Java’s garbage collector can greatly simplify programming and is safer when dealing with memory.
Make notes on the contents of the book | The link address |
---|---|
【 recommendation 】【Java programming ideas 】【 Notes 】 | Juejin. Cn/post / 684490… |
【 recommended 】【Java Core Technology Volume ⅰ 】 | Juejin. Cn/post / 684490… |
Later updates continue……
If there are writing mistakes, welcome to leave a message, I hope we can progress together, refueling together! 😜 😜