Three major JDK features in Java Basics 12

“This is the 12th day of my participation in the Gwen Challenge in November. See details of the event: The Last Gwen Challenge 2021”.

About the author

  • The authors introduce

🍓 Blog home page: author’s home page 🍓 Introduction: 🥇, a high quality creator in JAVA field, 🎓, a junior in college, participated in various provincial and national competitions and won a series of honors. 🍓 pay attention to me: pay attention to my learning materials, document download all have, regularly update the article every day, inspirational to do a JAVA senior program ape 👨💻.


Three major features of the JDK – generics

Generics can help us solve the problem of parameter conversion

The introduction of generics

What is the main purpose of generics? For example, we are now required to define a Point class that represents three types of coordinates:

Integer coordinates: x=10, y=20;

Decimal coordinates: x=10.1, y=20.3;

String data: x= 10 ° E, y= 20 ° W.

If you want to represent the above data, you must define two attributes x and Y, and each attribute can receive three data types, then only use the Object class to define the appropriate, which will occur the following conversion relations:

Integer: int→ automatic boxing to Integer→ upward transformation to Object;

Decimal: Double→ automatic packing to double→ upward transformation to Obejct;

String: String → Transform up to Obejct;

Set the plastic

package com.demo;
class Point {
	private Object x;
	private Object y;
	public Object getX(a) {
		return x;
	}
	public void setX(Object x) {
		this.x = x;
	}
	public Object getY(a) {
		return y;
	}
	public void setY(Object y) {
		this.y = y; }}public class PointDemo {
	public static void main(String[] args) {
		// Step 1: Set the data
		Point p = new Point();
		p.setX(10);
		p.setY(20);
		// Step 2: Retrieve data
		int x = (Integer)p.getX();
		int y = (Integer)p.getY();
		System.out.println("x = " + x + ",y = "+ y); }}Copy the code

Set the decimal

package com.demo;
class Point {
	private Object x;
	private Object y;
	public Object getX(a) {
		return x;
	}
	public void setX(Object x) {
		this.x = x;
	}
	public Object getY(a) {
		return y;
	}
	public void setY(Object y) {
		this.y = y; }}public class PointDemo {
	public static void main(String[] args) {
		// Step 1: Set the data
		Point p = new Point();
		p.setX(10.1);
		p.setY(20.2);
		// Step 2: Retrieve data
		double x = (Double)p.getX();
		double y = (Double)p.getY();
		System.out.println("x = " + x + ",y = "+ y); }}Copy the code

Set string

package com.demo;
class Point {
	private Object x;
	private Object y;
	public Object getX(a) {
		return x;
	}
	public void setX(Object x) {
		this.x = x;
	}
	public Object getY(a) {
		return y;
	}
	public void setY(Object y) {
		this.y = y; }}public class PointDemo {
	public static void main(String[] args) {
		// Step 1: Set the data
		Point p = new Point();
		p.setX("10" east longitude);
		p.setY("West longitude 20");
		// Step 2: Retrieve data
		String x = (String)p.getX();
		String y = (String)p.getY();
		System.out.println("x = " + x + ",y = "+ y); }}Copy the code

It looks like everything is done, and that’s all you can do based on what you’ve learned before, but there are a number of problems with this program.

This program to solve the key problem in the Object class, all types can be like Obejct conversion, but it is also it failed.

public class PointDemo {
	public static void main(String[] args) {
		Point point = new Point();
		// Set parameters
		point.setX(10);
		point.setY("North");
		// Retrieve parameters
		String x = (String) point.getX();
		String y = (String) point.getY();
		System.out.println("The coordinates of x are:"+x+"The y coordinate is:"+y); }}Copy the code

There is no syntax error because the number 10 is wrapped as an Integer and can be received using Obejct. Technically, there is no problem with this operation, but practically speaking, because there is no agreement, the following error message will be displayed during the process of retrieving data and performing the downward transformation:

Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
	at cn.mldn.demo.TestDemo.main(PointDemo.java:30)
Copy the code

Therefore, it can be concluded that there are security risks in the above programs that were not detected during the program compilation, and that generics can now be used to solve this problem.

Generic implementation

Generics: The parameter types of properties or methods operated on in a class are not declared when they are defined, but set dynamically when they are used.

package com.demo;
// What type of Point does the user define
class Point<T> {//T represents a parameter, a placeholder mark
	private T x;
	private T y;
	public T getX(a) {
		return x;
	}
	public void setX(T x) {
		this.x = x;
	}
	public T getY(a) {
		return y;
	}
	public void setY(T y) {
		this.y = y; }}public class PointDemo {
	public static void main(String[] args) {
		// Step 1: Set the data
		Point<String> p = new Point<String>();
		p.setX("10" east longitude);
		p.setY("West longitude 20");
		// Step 2: Retrieve data
		String x = p.getX();// Avoid a downward transition
		String y = p.getY();
		System.out.println("x = " + x + ",y = "+ y); }}Copy the code

The test does not have the operation relationship of downward transformation, so the program avoids the problem of security, and if the type of setting is not uniform, in the process of program compilation can also be very good to solve, directly will report syntax errors.

And when the user uses the Point class to declare objects without setting generics, the program will be warned during compilation, and to ensure that the program does not have errors, all types will be processed using Obejct. Using generics is a good way to solve the problem of data type unification.

A word of caution here, however, is that JDK1.5 and JDK1.7 define generics slightly differently.

In JDK1.5, we declare operations on generics

Point<String> p= new Point<String>();
Copy the code

This is the syntax for JDK1.5. You must set the generic type when you declare and instantiate an object.

This was simplified in JDK1.7

Point<String> p= new Point< >();
Copy the code

The generic type of the instantiated object is defined by the declared generic type.

The wildcard

The emergence of generics can indeed solve the problem of data unification and avoid the downward transformation operation, but it will also bring new problems, through a program, to observe what problems will arise?

Define a simple generic for simplicity

package com.demo;

class Message<T>{
	private T info;

	public T getInfo(a) {
		return info;
	}

	public void setInfo(T info) {
		this.info = info; }}Copy the code

The above class object is passed by reference

public class MessageDemo {
	public static void main(String[] args) {
		Message<String> msg = new Message<>();
		msg.setInfo("hello,world!");
		print(msg);// The above class object is passed by reference
	}
	public static void print(Message<String> s){ System.out.println(s.getInfo()); }}Copy the code

But what if the generic type now defined is not String? For example: int (can’t be a basic data type, can only be a wrapper class)

public class MessageDemo {
	public static void main(String[] args) {
		Message<Integer> msg = new Message<>();
		msg.setInfo(100);
		print(msg);// Cannot pass the reference
	}
	public static void print(Message<String> s){ System.out.println(s.getInfo()); }}Copy the code

If the print() method can no longer accept a reference to a Message object, it can override the print() method to accept a reference to a Message object

public class MessageDemo {
	public static void main(String[] args) {
		// TODO automatically generates method stubs
		Message<Integer> msg = new Message<>();
		msg.setInfo(100);
		print(msg);
	}
	public static void print(Message<String> msg){
		System.out.println(msg.getInfo());
	}
	public static void print(Message<Integer> msg){ System.out.println(msg.getInfo()); }}Copy the code

This time found that carried out in accordance with the previous method can’t method overloading, method of overloading didn’t say that definition for a class, because when method overloading observation is not a generic type, but the name of the class, or data type, so now can be found that this presents a generic class, is equivalent to a class is divided into several small classes.

So here’s the problem: the arguments received by the method are much more problematic than they were when object polymorphism was used to solve the problem, at least when overloading was used to receive all subclass objects of a class, but now overloading is not even possible.

At this point, someone suggested that you just don’t write generic types when you define methods.

You do not define generic types when defining methods

public class MessageDemo {
	public static void main(String[] args) {
		// TODO automatically generates method stubs
		Message<Integer> msg = new Message<>();
		msg.setInfo(100);
		print(msg);
	}
	public static void print(Message msg){ System.out.println(msg.getInfo()); }}Copy the code

Although the print() method now has a warning on its arguments, the program is fine, but a new problem arises. The problem is that there are no type restrictions on method operations.

public static void print(Message msg){
		msg.setInfo(100);
		System.out.println(msg.getInfo());
}
Copy the code

Print () : print() : print() : print() : print() : print() : print() And through this program also found, must find a way, : this method can receive any generic type Settings, and can not be modified, can only output, to solve such a problem, can use the wildcard “?” Said.

public static void print(Message
        msg){
		System.out.println(msg.getInfo());
}
Copy the code

Due to? There are many cases, especially when learning some class libraries, so for “?” Just remember, it’s any type, and if there’s an argument, it’ll return the same “?” , as an Object.

Now that WE’re talking about Obejct, there’s actually another question: For all of the subclasses, which are Object subclasses, can you accept if you use Object for all of your previous programs?

Message<String> msg = new Message<>();
Message<Object> s = msg;
Copy the code

Because the scope of Object is larger than the scope of String.

And in the wildcard “?” Two subsymbols are derived from:

  1. Set the upper limit of generics:? Extends class;

For example:? Extends Number, which can only be Number or a subclass of Number, Integer, etc.

2. Set the lower limit of generics:? Super class.

For example:? Super String, it can only be a String or a superclass of String Object

Set generic caps

package com.demo;

class Message<T extends Number>{
	private T info;

	public T getInfo(a) {
		return info;
	}

	public void setInfo(T info) {
		this.info = info; }}public class MessageDemo {
	public static void main(String[] args) {
		Message<Integer> msg = new Message<>();
		msg.setInfo(100);
        / / 100
		print(msg);
	}
	public static void print(Message<? extends Number> s){ System.out.println(s.getInfo()); }}Copy the code

Set the generic lower bound

package com.demo;

class Message<T>{
	private T info;

	public T getInfo(a) {
		return info;
	}

	public void setInfo(T info) {
		this.info = info; }}public class MessageDemo {
	public static void main(String[] args) {
		Message<String> msg = new Message<>();
		msg.setInfo("Hello,world! 100");
        //Hello,world! 100
		print(msg);
	}
	// Use the wildcard character "?" It can accept any data type, but cannot be modified because the type is uncertain
	public static void print(Message<? super String> s){ System.out.println(s.getInfo()); }}Copy the code

A generic interface

In all of the generics defined before, they are defined on classes, and interfaces can be generically defined, and interfaces that use generic definitions can be called generic interfaces.

interface Message<T>{
	public String echo(T msg);
}
Copy the code

There are two ways to implement generic interfaces in Java:

Method 1: Continue defining generics on subclasses, while the generics continue to be used on interfaces

package com.test;
interface IMessage<T>{
	public void print(T t);
}
class MessageImpl<T> implements IMessage<T>{

	@Override
	public void print(T t) {
		// TODO Auto-generated method stubSystem.out.println(t); }}public class MessageTest {
	public static void main(String[] args) {
		IMessage<String> msgimpl = new MessageImpl();
		msgimpl.print("Hello,world!!"); }}Copy the code

Method 2: Set a specific type on a subclass

package com.test;
interface IMessage<T>{
	public void print(T t);
}
class MessageImpl implements IMessage<String>{

	@Override
	public void print(String t) {
		// TODO Auto-generated method stubSystem.out.println(t); }}public class MessageTest {
	public static void main(String[] args) {
		IMessage<String> msgimpl = new MessageImpl();
		msgimpl.print("Hello,world!!"); }}Copy the code
3.5 Generic methods

For generics, you can define a method as well as a class, and the method does not have to be defined in the generic class.

public class TestDemo {
	public static void main(String[] args) {
		// TODO automatically generates method stubs
		Integer result[] = get(1.2.3);
		for(inttemp : result){ System.out.println(temp); }}public static <T> T[] get(T... date){
		returndate; }}Copy the code

The three main JDK features — enumerations

Before we look at enumerations, we’ll review the concept of the multi-case design pattern, where the constructor is private (not public), and then there are several specified objects inside the class, and a method returns the specified object.

Multiple cases and enumeration

Defines a multi-case design class that describes a color base color

package com.demo;
class Color {
	private static final Color RED = new Color("Red");
	private static final Color GREEN = new Color("Green");
	private static final Color BLUE = new Color("Blue");
	private String title;
	private Color(String title){
		this.title=title;
	}
	public String toString(a){
		return this.title;
	}
	public static Color getColor(int num){
		switch(num){
		case 0:
		return RED;
		case 1:
		return GREEN;
		case 2:
		return BLUE;
		default:
		return null; }}}public class ColorDemo {
	public static void main(String[] args) {
		Color c = Color.getColor(0); System.out.println(c); }}Copy the code

Development based on enumeration

package com.demo;
enum Color {
	RED,BULE,PINK;
}
public class ColorDemo {
	public static void main(String[] args) { System.out.println(Color.RED); }}Copy the code

An Enum

Enumerations are not a new type in Java. Strictly speaking, every class defined using an enum is actually a class that inherits an enum parent, and the java.lang.Enum class is defined as follows:

public abstract class Enum<E extends Enum<E>>
extends Object
implements Comparable<E>, Serializable
Copy the code

The Enum class defines two methods:

  1. Public final int ordinal();
  2. Getenumeration name: public Final String name().
package com.demo;
enum Color {
	RED,BULE,PINK;
}
public class ColorDemo {
	public static void main(String[] args) {
		//0===RED
		System.out.println(Color.RED.ordinal() + "= = ="+ Color.RED.name()); }}Copy the code

Get all color data

package com.demo;
enum Color {
	RED,BULE,PINK;
}
public class ColorDemo {
	public static void main(String[] args) {
				/*0===RED 1===BULE 2===PINK*/
		for (Color c : Color.values()) {
			System.out.println(c.ordinal() + "= = ="+ c.name()); }}}Copy the code

Interview question: Explain the difference between enum and enum?

Enum is a keyword, and an enumerated class defined using enum is essentially a class that inherits enum classes.

Enumeration defines additional structures

Understood, before enumeration is more cases of design patterns, so now that is more cases of design patterns, for classes will certainly have a variety of components, including the properties, methods, constructors, also can be defined in the enumeration of above content, but it is important to note that the enumeration class definition of constructor must not be public, must be private.

In addition to these requirements, each object defined in the enumeration must be defined on the first line.

package com.demo;
enum Color {
	RED("Red"),BULE("Blue"),PINK("Pink");
	private String c;
	private Color(String c){
		this.c = c;
	}
	public String toString(a){
		return this.c; }}public class ColorDemo {
	public static void main(String[] args) {
				Red / * * /System.out.println(Color.RED); }}Copy the code

The enumeration interface

package com.demo;
interface IColor{
	public String getColor(a);
}
enum Color implements IColor{
	RED("Red"),BULE("Blue"),PINK("Pink");
	private String c;
	private Color(String c){
		this.c = c;
	}
	public String toString(a){
		return this.c;
	}
	@Override
	public String getColor(a) {
		// TODO Auto-generated method stub
		return this.c; }}public class ColorDemo {
	public static void main(String[] args) {
				Red / * * /System.out.println(Color.RED); }}Copy the code

Enumeration application

Only a few objects are specified

gender

package com.demo;
class Person{
	private String name;
	private int age;
	private Sex sex;
	public Person(String name, int age, Sex sex) {
		super(a);this.name = name;
		this.age = age;
		this.sex = sex;
	}
	@Override
	public String toString(a) {
		return "Person [name=" + name + ", age=" + age + ", sex=" + sex + "]"; }}enum Sex{
	MALE("Male"),FEMALE("Female");
	private	String sex;

	private Sex(String sex) {
		this.sex = sex;
	}
	public String toString(a){
		return this.sex; }}public class MaleDemo {
	public static void main(String[] args) {
		Person person = new Person("jack".10, Sex.MALE); System.out.println(person.toString()); }}Copy the code

Enumerations can also be written and judged by switch statements.

The three main features of the JDK — annotations

After JDK1.5, applications are allowed to define applications by means of annotations, and there are three annotations in JavaSE: @Override, @deprecated and @SuppressWarnings.

Exact Override: @override

Method overwrite: In an inheritance relationship, a subclass defines an overwrite with the same method name, parameter type, and number as the parent class. The overwrite method cannot have stricter access control rights than the parent class.

package com.annotation;
class Person{
	// Now you want toString() overridden, but unfortunately because of your own typing errors, the method overridden
	//@Override
	public String tostring(a){// Now we want to override the toString() method
		return "Alone"; }}public class Demo1 {
	public static void main(String[] args) {
		System.out.println(newPerson().tostring()); }}Copy the code

This time is not called overwrite, it is your own definition of an extension method, most importantly, this problem in the program compilation does not show up. But now to keep our Override method strict, we can use an annotation (@override) to check if the method is determined to be overridden

, there will be no syntax error, if successful overwrite, considered syntax error.

package com.annotation;
class Person{
	// Now you want toString() overridden, but unfortunately because of your own typing errors, the method overridden
	public String toString(a){// Now we want to override the toString() method
		return "Alone"; }}public class Demo1 {
	public static void main(String[] args) {
		System.out.println(newPerson()); }}Copy the code

Declare an expired operation: @deprecated

For application development, often some classes used to modify or maintain, if a method of a class, now might be a start to launch the normal use, but in a later version there are some problems, don’t want people to go after the modification of using these methods, then certainly cannot delete directly, because if directly deleted, So the best thing to do is tell the user that this method has a problem and is no longer recommended, and use the “@deprecated” declaration in this case.

package com.annotation;
class Person1{
	@Deprecated// Indicates that this method is not recommended. No error will be reported even if it is used
	public Person1(a){}
	public Person1(String name){}
	@Deprecated
	public void print(a){}}public class Demo2 {
	public static void main(String[] args) {
		Person1 person = new Person1();// Explicitly mark expirationperson.print(); }}Copy the code

Suppress warnings: @SuppressWarning

If the program is compiled with a warning but there is no error but there are some security risks, it will certainly inform the user, so do not want it to display, add suppression warning message.

package com.annotation;
class Person1<T>{
	@Deprecated// Indicates that this method is not recommended. No error will be reported even if it is used
	public Person1(a){}
	public Person1(String name){}
	@Deprecated
	public void print(a){}}public class Demo2 {
	@SuppressWarnings("rawtypes")
	public static void main(String[] args) {
		Person1 person = new Person1();// Explicitly mark expirationperson.print(); }}Copy the code

About the development mode of software;

The first stage: all the operations will be written in the program, such as: network program, connection program, connected server address, user authentication, etc.;

The second stage: program + configuration file, configuration file and program separation, too many configuration files, very complicated later modification;

Stage 3: Write the configuration file back into the program, but effectively separate it from the program.