Uso, uso e exemplos de static, this, super, final em Java

Link original: https://www.cnblogs.com/zjfjava/p/6337932.html
1. estático

Por favor, observe primeiro o seguinte programa:

public class Hello {
	public static void main(String[] args){ //(1)
	System.out.println("Hello,world!"); //(2) }
}

Depois de ler este programa, não é estranho para a maioria das pessoas que estudou Java. Mesmo se você não aprendeu Java e aprendeu outras linguagens de alto nível, como C, deve entender o significado desse código. Ele simplesmente gera "Olá, mundo" e não tem outro uso, mas mostra o uso principal da palavra-chave estática.

Em 1, definimos um método estático chamado main, o que significa dizer ao compilador Java que eu posso usar esse método sem criar um objeto desse tipo. Você ainda precisa executar este programa? Geralmente, inserimos os seguintes comandos na linha de comando (sublinhados para entrada manual):

javac Hello.java

java Hello

Hello,world!

Este é o processo que você executa: a primeira linha é usada para compilar o arquivo Hello.java. Após a execução, se você observar o atual, encontrará um arquivo Hello.class adicional, que é o código de byte binário Java gerado pela primeira linha. . A segunda linha é a maneira mais comum de executar um programa Java. Os resultados da execução são os esperados. Em 2, você pode se perguntar por que isso é necessário para a saída. Ok, vamos quebrar essa frase. (Se a documentação Java não estiver instalada, acesse o site oficial da Sun para navegar na API do J2SE) Primeiro, o System é uma classe principal localizada no pacote java.lang. Se você olhar para a sua definição, encontrará uma linha como esta: public static final PrintStream Então vá além, clique no hiperlink PrintStream, na página METHOD, você verá vários métodos definidos, encontre println, haverá uma linha como esta:

public void println(String x)

Ok, agora você deve entender por que devemos chamá-lo dessa maneira, out é uma variável estática do System, para que possa ser usado diretamente, e a classe à qual pertence pertence possui um método println.

Método estático

Geralmente, um método é definido como estático em uma classe, ou seja, esse método pode ser chamado sem o objeto dessa classe. Como mostrado abaixo:

class Simple{
	static void go(){
		System.out.println("Go...");
	}
}
 
public class Cal{
	public static void main(String[] args){
    	Simple.go();
	 }
}

Chamar um método estático é "nome da classe. Nome do método", o uso do método estático é muito simples, como mostrado acima. Em geral, os métodos estáticos geralmente fornecem algumas ferramentas utilitárias para outras classes no aplicativo.Um grande número de métodos estáticos na biblioteca de classes Java é definido para esse fim.

Variável estática

Variáveis ​​estáticas são semelhantes aos métodos estáticos. Todas essas instâncias compartilham essa variável estática, ou seja, quando a classe é carregada, apenas um espaço de armazenamento é alocado e todos esses objetos podem manipular esse espaço de armazenamento em bloco; é claro, isso é outra questão para final. Veja o seguinte código:

class Value{
	static int c=0;
	static void inc(){
	c++;
	}
}
class Count{
	public static void prt(String s){
		System.out.println(s);
	}
	public static void main(String[] args){
		Value v1,v2;
		v1=new Value();
		v2=new Value();
		prt("v1.c="+v1.c+" v2.c="+v2.c);
		v1.inc();
		prt("v1.c="+v1.c+" v2.c="+v2.c); 
	}
}

Os resultados são os seguintes:

v1.c=0 v2.c=0
v1.c=1 v2.c=1

Isso prova que eles compartilham uma área de armazenamento. Variáveis ​​estáticas são um pouco semelhantes ao conceito de variáveis ​​globais em C. Vale a pena discutir a inicialização de variáveis ​​estáticas. Nós modificamos o programa acima:

class Value{
	static int c=0;
	Value(){
		c=15;
	}
	Value(int i){
		c=i;
	}
	static void inc(){
		c++;
	}
}
class Count{
	public static void prt(String s){
		System.out.println(s);
	}
	Value v=new Value(10);
	static Value v1,v2;
	Static{
		prt("v1.c="+v1.c+" v2.c="+v2.c);
		v1=new Value(27);
		prt("v1.c="+v1.c+" v2.c="+v2.c);
		v2=new Value(15);
		prt("v1.c="+v1.c+" v2.c="+v2.c);
	}
	public static void main(String[] args){
		Count ct=new Count();
		prt("ct.c="+ct.v.c);
		prt("v1.c="+v1.c+" v2.c="+v2.c);
		v1.inc();
		prt("v1.c="+v1.c+" v2.c="+v2.c);
		prt("ct.c="+ct.v.c);
	}
}

Os resultados são os seguintes:

v1.c=0 v2.c=0

v1.c=27 v2.c=27

v1.c=15 v2.c=15

ct.c=10

v1.c=10 v2.c=10

v1.c=11 v2.c=11

ct.c=11

Este programa demonstra várias características da inicialização estática. Se você é novo no Java, os resultados podem surpreendê-lo. Você pode ficar confuso adicionando parênteses após a estática. A primeira coisa a dizer é que as variáveis ​​definidas estaticamente terão precedência sobre quaisquer outras variáveis ​​não estáticas, independentemente da ordem em que elas aparecerem. Conforme mostrado no programa, embora v apareça antes de v1 e v2, o resultado é que a inicialização de v1 e v2 precede v. O static {é seguido por um pedaço de código, usado para a inicialização explícita da variável estática. Esse código será inicializado apenas uma vez e quando a classe for carregada pela primeira vez. Se você pode ler e entender esse código, ele ajudará a entender a palavra-chave estática. Quando se trata de herança, as variáveis ​​estáticas da classe pai serão inicializadas primeiro, depois as subclasses e assim por diante. Variáveis ​​não estáticas não são o assunto deste artigo e não serão discutidas em detalhes aqui.Por favor, consulte a explicação em Think in Java.

Classe estática

Normalmente, uma classe comum não pode ser declarada estática, apenas uma classe interna pode. No momento, a classe interna declarada como estática pode ser usada diretamente como uma classe normal sem precisar instanciar uma classe externa.

Conforme mostrado no código a seguir:

public class StaticCls{
	public static void main(String[] args){
		OuterCls.InnerCls oi=new OuterCls.InnerCls();
	}
}
class OuterCls{
	public static class InnerCls{
		InnerCls(){
		System.out.println("InnerCls");
		}
	}
}

A saída será a esperada.

InnerCls

O mesmo que a classe comum. Para outro uso de classes internas, consulte os capítulos relevantes no Think in Java, que não serão explicados em detalhes aqui.

、 Isso & super

Na seção anterior, discutimos vários usos da estática. Ao usar a estática para definir métodos ou membros, ela fornece alguma comodidade para a nossa programação.Em certa medida, pode-se dizer que é semelhante às funções globais e variáveis ​​globais na linguagem C. . No entanto, isso não significa que, com essa conveniência, você possa usá-lo em qualquer lugar, caso seja necessário, considere seriamente se está programando com o pensamento orientado a objetos e se o seu programa é orientado a objetos. Ok, agora vamos discutir o significado e o uso das duas palavras-chave this & super.

Em Java, isso geralmente se refere ao objeto atual e super se refere à classe pai. Quando você deseja fazer referência a algo no objeto atual, como um método do objeto atual ou um membro do objeto atual, pode usá-lo para atingir esse objetivo, é claro, outro uso disso é chamar o objeto atual Outro construtor, estes serão discutidos em breve. Se você quiser se referir a algo na classe pai, é super. Como este e super têm algumas características semelhantes e um certo relacionamento inerente, discutiremos isso nesta seção, na esperança de ajudá-lo a diferenciá-los e dominá-los.

No método geral, a situação mais comum é que um nome formal de parâmetro em seu método tenha o mesmo nome que um membro do objeto atual.Neste momento, para não ficar confuso, você precisa usar essa palavra-chave explicitamente. Indique que você deseja usar um membro, o método é "this. Member name" e o método sem esse é o parâmetro formal. Além disso, você também pode usar "this. Method name" para se referir a um método do objeto atual, mas isso não é necessário no momento, você pode usar diretamente o nome do método para acessar esse método, o compilador saberá que você está chamando Aquele. O código a seguir demonstra o uso acima:

public class DemoThis{
	private String name;
	private int age;
	DemoThis(String name,int age){
		setName(name); //你可以加上this来调用方法,像这样:this.setName(name);但这并不是必须的
		setAge(age);
		this.print();
	} 
	public void setName(String name){
		this.name=name;//此处必须指明你要引用成员变量
	}
	public void setAge(int age){
		this.age=age;
	}
	public void print(){
		System.out.println("Name="+name+" Age="+age);//在此行中并不需要用this,因为没有会导致混淆的东西
	}
	public static void main(String[] args){
		DemoThis dt=new DemoThis("Kevin","22");
	}
}

Este código é muito simples e você deve poder lê-lo sem explicação. Você vê this.print () no construtor. Você pode substituí-lo por print (). Ambos têm o mesmo efeito. Abaixo, modificamos este programa para demonstrar o uso de super.

class Person{
	public int c;
	private String name;
	private int age;
	protected void setName(String name){
		this.name=name;
	}
	protected void setAge(int age){
		this.age=age;
	}
	protected void print(){
		System.out.println("Name="+name+" Age="+age);
	}
}
 
public class DemoSuper extends Person{
	public void print(){
		System.out.println("DemoSuper:");
		super.print();
	}
	public static void main(String[] args){
		DemoSuper ds=new DemoSuper();
		ds.setName("kevin");
		ds.setAge(22);
		ds.print();
	}
}

No DemoSuper, o método de impressão redefinido substitui o método de impressão da classe pai, primeiro faz suas próprias coisas e depois chama o método substituído da classe pai. A saída mostra isso:

DemoSuper:

Name=kevin Age=22

Este método de uso é relativamente comum. Além disso, se os membros da classe pai puderem ser acessados ​​pela classe filho, você poderá usá-lo dessa maneira, usando o "super. Nome do membro na classe pai", mas geralmente não acessará o nome do membro na classe pai como este .

O construtor é um método especial chamado automaticamente quando o objeto é inicializado. No construtor, this e super também têm vários usos mencionados acima e possuem locais especiais, consulte o seguinte exemplo:

class Person{
	public static void prt(String s){
		System.out.println(s);
	}
	
	Person(){
		prt("A Person.");
	}
	
	Person(String name){
		prt("A person name is:"+name);
	}
}

public class Chinese extends Person{
	Chinese(){
		super(); //调用父类构造函数(1)
		prt("A chinese.");//(4)
	}
	Chinese(String name){
		super(name);//调用父类具有相同形参的构造函数(2)
		prt("his name is:"+name);
	}
	Chinese(String name,int age){
		this(name);//调用当前具有相同形参的构造函数(3)
		prt("his age is:"+age);
	}

	public static void main(String[] args){
		Chinese cn=new Chinese();
		cn=new Chinese("kevin");
		cn=new Chinese("kevin",22);
	}
}

Neste programa, este e super não usam mais "." Para conectar um método ou membro como antes, mas acompanhando diretamente os parâmetros apropriados, portanto, seu significado mudou. O parâmetro after super é usado para chamar o construtor da mesma forma na classe pai, como 1 e 2. Adicionar parâmetros depois disso chama o construtor atual com os mesmos parâmetros, como 3. Obviamente, nos vários construtores sobrecarregados de chinês, ainda podem ser usados ​​vários usos disso e métodos super em geral, como 4 locais, você pode substituí-lo por "this.prt" (porque herda a classe pai O método in) ou "super.prt" (por ser um método na classe pai e pode ser acessado pela subclasse), ele ainda pode ser executado corretamente. Mas isso parece adicionar um pouco de sabor.

Por fim, escrevi muito: se você se lembrar da frase "isso geralmente se refere ao objeto atual, super geralmente se refere à classe pai", esse artigo alcançou seu objetivo e outras vontades serão praticadas em programação futura. Lentamente, realize e domine-o. Além disso, em relação à herança mencionada neste artigo, consulte o tutorial Java relevante.

Três final

Final não é comumente usado em Java, mas fornece funções como definir constantes na linguagem C. Além disso, final também permite controlar se seus membros, métodos ou classe podem ser substituídos ou herdados, etc. Funções, essas características tornam final uma posição indispensável em Java e também é uma das palavras-chave que devem ser conhecidas e dominadas ao aprender Java.

membro final

Ao definir uma variável em uma classe, adicione a palavra-chave final à sua frente, ou seja, uma vez inicializada, ela não poderá ser alterada.O significado imutável aqui é que o valor do tipo básico é imutável e Para variáveis ​​de objeto, a referência não pode ser alterada. Sua inicialização pode estar em dois lugares, um é a sua definição, o que significa que ele é atribuído diretamente à variável final quando é definido, e o outro está no construtor. Você pode escolher apenas um desses dois locais. Você pode atribuir um valor ao defini-lo ou atribuir um valor ao construtor. Não é possível atribuir um valor ao defini-lo e outro valor no construtor. O código a seguir demonstra isso:

import java.util.List;

import java.util.ArrayList;

import java.util.LinkedList;

public class Bat{
	final PI=3.14; //在定义时便给址值
	final int i; //因为要在构造函数中进行初始化,所以此处便不可再给值
	final List list; //此变量也与上面的一样

	Bat(){
		i=100;
		list=new LinkedList();
	}

	Bat(int ii,List l){
		i=ii;
		list=l;
	}

	public static void main(String[] args){
		Bat b=new Bat();
		b.list.add(new Bat());
		//b.i=25;
		//b.list=new ArrayList();
		System.out.println("I="+b.i+" List Type:"+b.list.getClass());
		b=new Bat(23,new ArrayList());
   		b.list.add(new Bat());
		System.out.println("I="+b.i+" List Type:"+b.list.getClass());
	}
}

Este programa simplesmente demonstra o uso regular de final. Use o método de inicialização no construtor aqui, o que oferece um pouco de flexibilidade. Conforme mostrado nos dois construtores sobrecarregados do Bat, o primeiro construtor padrão fornecerá o valor padrão e o construtor sobrecarregado inicializará a variável final de acordo com o valor ou o tipo que você fornecer. No entanto, às vezes você não precisa dessa flexibilidade, apenas precisa atribuir seu valor quando está definido e nunca muda, e não use esse método novamente. Existem duas linhas de comentários no método principal: se você remover o comentário, o programa não poderá ser compilado, o que significa que, independentemente do valor de i ou do tipo de lista, uma vez inicializado, ele não poderá mais ser alterado. No entanto, b pode ser reinicializado para especificar o valor de i ou o tipo de lista, que é mostrado na saída:

I=100 List Type:class java.util.LinkedList

I=23 List Type:class java.util.ArrayList

Outro uso é definir o parâmetro no método como final.Para variáveis ​​do tipo básico, isso não tem significado prático, porque as variáveis ​​do tipo básico são passadas por valor ao chamar o método, ou seja, você pode alterá-lo Essa variável de parâmetro não afeta a instrução de chamada, mas é muito prática para a variável de objeto, porque a variável de objeto recebe sua referência quando passada, para que sua modificação da variável de objeto no método também afete a instrução de chamada Variáveis ​​de objeto, quando você não precisar alterar a variável de objeto como parâmetro no método, use explicitamente final para declarar, o que impedirá que você a modifique inadvertidamente e afete o método de chamada.

Além disso, quando a classe interna no método usa o parâmetro no método, esse parâmetro também deve ser declarado como final antes de poder ser usado, conforme mostrado no código a seguir:

public class INClass{
	void innerClass(final String str){
		class Iclass{
			IClass(){
				System.out.println(str);
			}
		}
	IClass ic=new IClass();
	}

	public static void main(String[] args){
		INClass inc=new INClass();
		inc.innerClass("Hello");
	}
}

método final

Declare o método como final, o que significa que você já sabe que a função fornecida por esse método atendeu aos seus requisitos, nenhuma extensão é necessária e nenhuma classe que herda dessa classe pode substituir esse método, mas a herança ainda pode herdar esse método , O que significa que pode ser usado diretamente. Há também um mecanismo chamado inline, que permite inserir diretamente o corpo do método no local de chamada ao chamar o método final, em vez de fazer chamadas de rotina, como salvar pontos de interrupção, empurrar a pilha, etc. Torne seu programa mais eficiente.No entanto, quando o corpo do método for muito grande ou você chamar esse método em vários locais, o código do corpo da chamada será expandido rapidamente, o que pode afetar a eficiência, portanto, você deve usá-lo com cuidado Definição final do método.

aula final

Quando você usa final em uma classe, precisa pensar com cuidado, porque uma classe final não pode ser herdada por ninguém, isso significa que essa classe é uma classe de folha em uma árvore de herança e o design dessa classe Foi considerado perfeito sem modificação ou expansão. Para os membros da classe final, você pode defini-la como final ou não. Para o método, como a classe pertence ao relacionamento final, ela naturalmente se torna final. Você também pode adicionar explicitamente um método final à classe final, mas isso obviamente não tem sentido.

O programa a seguir demonstra o uso de métodos finais e classes finais:

final class final{
	final String str="final Data";
	public String str1="non final data";
	final public void print(){
		System.out.println("final method.");
	}
	public void what(){
		System.out.println(str+""+str1);
	}
}
public class FinalDemo{ //extends final 无法继承
	public static void main(String[] args){
		final f=new final();
		f.what();
		f.print();
	}
}

Pode ser visto no programa que o uso da classe final é quase o mesmo que o da classe comum, exceto que ele perde as características herdadas. A diferença entre o método final e o não final também é difícil de ver na linha do programa, lembre-se de usá-lo com cautela.

Aplicação final no modo de design

Existe um padrão no padrão de design chamado padrão invariável.Este padrão pode ser facilmente implementado em Java através da palavra-chave final.O programa Bat.java usado ao explicar o membro final é um exemplo de padrão invariável. Se você estiver interessado nisso, consulte a explicação no livro "Java and Patterns", escrito pelo Dr. Yan Hong.

Até agora, o uso deste estático, supert e final foi concluído.Se você já pode dizer a diferença e o uso dessas quatro palavras-chave, significa que você o domina basicamente. No entanto, nada no mundo é perfeito.O Java fornece essas quatro palavras-chave, o que traz grande comodidade aos programadores, mas não permite que você as use em todos os lugares. Isso é contraproducente, portanto, considere cuidadosamente ao usá-lo.
<Comentários: O conteúdo do blogueiro original está bem escrito, mas acho que esse estilo de código é realmente uma dor de cabeça>

Lançado seis artigos originais · ganhou elogios 0 · Vistas 4855

Acho que você gosta

Origin blog.csdn.net/weixin_44479378/article/details/93055589
Recomendado
Clasificación