GVKun编程网logo

一篇文章带你搞定JAVA注解(一篇文章带你搞定java注解的软件)

14

这篇文章主要围绕一篇文章带你搞定JAVA注解和一篇文章带你搞定java注解的软件展开,旨在为您提供一份详细的参考资料。我们将全面介绍一篇文章带你搞定JAVA注解的优缺点,解答一篇文章带你搞定java注

这篇文章主要围绕一篇文章带你搞定JAVA注解一篇文章带你搞定java注解的软件展开,旨在为您提供一份详细的参考资料。我们将全面介绍一篇文章带你搞定JAVA注解的优缺点,解答一篇文章带你搞定java注解的软件的相关问题,同时也会为您带来一篇文章带你了解Java基础-多态、一篇文章带你了解Java基础-接口、一篇文章带你入门Java修饰符、一篇文章带你入门Java基本概念的实用方法。

本文目录一览:

一篇文章带你搞定JAVA注解(一篇文章带你搞定java注解的软件)

一篇文章带你搞定JAVA注解(一篇文章带你搞定java注解的软件)

这篇文章主要介绍了详解Java注解的实现与使用方法的相关资料,希望通过本文大家能够理解掌握Java注解的知识,需要的朋友可以参考下

目录

1、注解是什么

2、jdk支持的注解有哪些

2.1 三种常用的注解:

2.2 元注解

3、注解实例

1、自定义注解

2、在对应的方法上增加注解

3、在项目启动的时候检查注解的枚举

4、总结

1、注解是什么

Java 注解用于为 Java 代码提供元数据,看完这句话也许你还是一脸懵逼,用人话说就是注解不直接影响你的代码执行,仅提供信息。接下我将从注解的定义、元注解、注解属性、自定义注解、注解解析JDK 提供的注解这几个方面再次了解注解(Annotation)

2、jdk支持的注解有哪些

2.1 三种常用的注解:

@SuppressWarnings 注解的作用是阻止编译器发出某些警告信息。它可以有以下参数:

deprecation :过时的类或方法警告。

unchecked:执行了未检查的转换时警告。

allthrough:当Switch程序块直接通往下一种情况而没有Break时的警告。

path:在类路径、源文件路径等中有不存在的路径时的警告。

serial:当在可序列化的类上缺少serialVersionUID定义时的警告。

finally:任何finally子句不能完成时的警告。

all:关于以上所有情况的警告

@Deprecated 该注解的作用是标记某个过时的类或方法。

@Override 该注解用在方法前面,用来标识该方法是重写父类的某个方法。

2.2 元注解

元注解主要是用来注解自定义注解的注解,分别有@Retention、 @Target、 @Document、 @Inherited和@Repeatable(JDK1.8加入)五种。

下面讲两个平常最常用的注解:

@Retention 注解的生命周期,主要有

RetentionPolicy.soURCE 仅存在于源码中

RetentionPolicy.CLASS 默认的策略,在class字节码文件中存在,但运行时无法获得 RetentionPolicy.RUNTIME 在运行时可以通过反射获取到,也是最常用的。

@Target 注解的作用目标,主要有

ElementType.TYPE 作用接口、类、枚举、注解

ElementType.FIELD 作用属性字段、枚举的常量

ElementType.METHOD 作用方法

ElementType.ParaMETER 作用方法参数

ElementType.CONSTRUCTOR 作用构造函数

ElementType.LOCAL_VARIABLE 作用局部变量

ElementType.ANNOTATION_TYPE 作用于注解(@Retention注解中就使用该属性) ElementType.PACKAGE 作用于包 ElementType.TYPE_ParaMETER 作用于类型泛型,即泛型方法、泛型类、泛型接口 (jdk1.8加入)

3、注解实例

在枚举中编译器只会限制枚举的名字不能重复,在开发中经常会遇到枚举Id 重复的问题,因为每个人在开发功能的时候一般只会专注于自己的功能,做完只会直接提交代码,不会注意到枚举Id冲突,这个时候可以使用下面的代码进行枚举自检,在项目的开发阶段就能及时发现代码的问题。下面的代码稍微修改下就可以在项目中使用,拿走不写。

1、自定义注解

检测枚举的key 是否有重复

package org.pdool.anno; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * @author 香菜 */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface CheckEnum { }

2、在对应的方法上增加注解

package org.pdool.anno; /** * 资源枚举类 * @author 香菜 */ public enum ResType { GOLD(1), DIAMOND(2), //注意:此处重复 SILVER(2); int type; @CheckEnum public int getType() { return type; } ResType(int type) { this.type = type; } }

3、在项目启动的时候检查注解的枚举

package org.pdool.anno; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashSet; import java.util.Set; /** * @author 香菜 */ public class Aain { public static void main(String[] args) throws InvocationTargetException,illegalaccessexception { // 获取有注解的方法 Method[] declaredMethods = ResType.class.getDeclaredMethods(); Method annoMethod = null; for (Method declaredMethod : declaredMethods) { CheckEnum annotation = declaredMethod.getAnnotation(CheckEnum.class); if (annotation != null){ annoMethod = declaredMethod; break; } } Set set = new HashSet(); // 遍历每个枚举的id Object[] oo = ResType.class.getEnumConstants(); for (Object o : oo) { Object invoke = annoMethod.invoke(o); if (!set.contains(invoke)){ set.add(invoke); }else { System.out.println("重复的key "+ o +" -- "+ invoke); } } } }

注:上面的代码只是简单的实例,只是为了展示核心代码,在项目中使用时可以修改类的获取为扫描项目下的包,遍历所有的枚举,就可以在项目中使用了。

4、总结

注解虽然不影响代码的运行,但是可以为运行中的程序提供更多的信息,注解也是很多框架的基本技术切入点,比如Spring 的注解,Lombok 的各种注解,都是使用了注解做了很多事,明白了注解是怎么回事,理解框架也会轻而易举。

本篇文章就到这里了,希望能给你带来帮助,也希望您能够多多关注小编的更多内容!

一篇文章带你了解Java基础-多态

一篇文章带你了解Java基础-多态

这篇文章主要介绍了Java 多态的深入理解的相关资料,子类继承父类的特征和行为,使得子类具有父类的各种属性和方法。或子类从父类继承方法,使得子类具有父类相同的行为,需要的朋友可以参考下

目录

Java基础知识(多态)

多态

多态的定义和存在的必要条件

多态的案例

多态的弊端

引用类型转换

总结

Java基础知识(多态)

多态

多态就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量到底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。

因为在程序运行时才确定具体的类,这样,不用修改源程序代码,就可以让引用变量绑定到各种不同的类实现上,从而导致该引用调用的具体方法随之改变,即不修改程序代码就可以改变程序运行时所绑定的具体代码,让程序可以选择多个运行状态,这就是多态性。

多态的定义和存在的必要条件

多态的定义:

多态是指同一个行为具有多个不同表现形式或形态的能力。

多态就是同一个接口,使用不同的实例而执行不同操作。

就举动物类的例子吧,cat和dog都是属于动物这一类,而动物呢,都有一个共同的行为就是吃吧,而不同的动物所吃的食物都大不相同吧!

猫呢,它喜欢吃鱼!

而对于狗呢,它就比较喜欢啃骨头!

所以多态就是对于吃这一行为来说,每种动物对吃这一行为所表现的行为都不尽相同。

多态存在的三个必要条件

1.继承或者实现

在多态中必须存在有继承或者实现关系的子类和父类。

2.方法的重写

子类对父类中某些方法进行重新定义(重写),在调用这些方法时就会调用子类的方法。

3.基类引用指向派生类对象,即父类引用指向子类对象

父类类型:指子类对象继承的父类类型,或者实现的父接口类型。

多态的格式:

父类类型 变量名 = new 子类类型(); 变量名.方法名();

多态格式可以充分体现了同一个接口,使用不同的实例而执行不同操作。

接下来我们具体来进行案例体会体会吧!

多态的案例

多态我们首先要知道的一点:

当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,执行的是子类重写后方法。如果子类没有重写该方法,就会调用父类的该方法。

总结起来就是:编译看左边,运行看右边。

首先我们先定义一个父类动物类,动物有吃的行为!

接着定义一个猫类和狗类去继承动物类,重写里面的吃行为!

具体代码如下:

定义动物父类:

package com.nz.pojo; /** * 先定义一个父类 --> 动物类 * 动物都有一个吃的行为属性 */ public class Animal { public void eat() { System.out.println("动物它们都会吃东西!!!"); } }

定义猫咪子类:

package com.nz.pojo; /** * 定义猫类继承动物类, * 随之重写里面的吃行为,因为猫也有吃的行为,但是猫喜欢吃罐头 */ public class Cat extends Animal{ public void eat() { System.out.println("小喵咪都喜欢吃鱼罐头!"); } }

定义小狗子类:

package com.nz.pojo; /** * 定义狗类继承动物类, * 随之重写里面的吃行为,因为狗也有吃的行为,但是狗喜欢啃骨头 */ public class Dog extends Animal{ public void eat() { System.out.println("小狗狗都爱啃骨头!"); } }

定义测试类,测试多态的形式:

package com.nz; import com.nz.pojo.Animal; import com.nz.pojo.Cat; import com.nz.pojo.Dog; /** * 测试多态的形式 */ public class Demo { public static void main(String[] args) { // 多态形式,创建猫类对象 Animal animal = new Cat(); // 调用的是Cat的 eat animal.eat(); // 多态形式,创建狗类对象 Animal animal2 = new Dog(); // 调用的是Dog的eat animal2.eat(); } }

得到的结果:

小喵咪都喜欢吃鱼罐头!

小狗狗都爱啃骨头!

类的大致结构:

可以看出我们可以使用多态的属性得到不同的动物的一个吃的行为属性!

多态的好处

提高了代码的拓展性,使用父类类型作为方法形式参数,传递子类对象给方法,进行方法的调用。

具体我们来看看吧:

继续使用上述的动物类、猫类、狗类吧。

定义测试类:

package com.nz; import com.nz.pojo.Animal; import com.nz.pojo.Cat; import com.nz.pojo.Dog; /** * 测试多态的好处 */ public class Demo2 { public static void main(String[] args) { // 创建猫和狗对象 Cat cat = new Cat(); Dog dog = new Dog(); // 调用catEat catEat(cat); // 调用dogEat dogEat(dog); /* 多态的好处: 以上各个动物的吃的方法, 我们都可以使用animalEat(Animal a)方法来代替。 并且执行效果都一样, 所以我们可以使用animalEat直接替代了不同动物的吃方法。 */ animalEat(cat); animalEat(dog); } /* 定义几个不同吃的方法,看看具体调用后的结果是什么吧! */ public static void catEat (Cat cat){ cat.eat(); } public static void dogEat (Dog dog){ dog.eat(); } public static void animalEat (Animal animal){ animal.eat(); } }

执行结果:

小喵咪都喜欢吃鱼罐头!

小狗狗都爱啃骨头!

小喵咪都喜欢吃鱼罐头!

小狗狗都爱啃骨头!

可以看出,由于多态的特性,我们的animalEat()方法传入的Animal类型参数,并且它是我们的Cat和Dog的父类类型,父类类型接收子类对象,所以我们可以将Cat对象和Dog对象,传递给animalEat()方法。

所以我们可以完全使用animalEat()方法来替代catEat()方法和dogEat()方法,达到同样的效果!以至于我们可以不必再单独写xxxEat()方法来传入指定的动物参数了,从而实现了实现类的自动切换。

所以多态的好处体现在:可以使我们的程序编写的更简单,并有良好的扩展性。

多态的弊端

从上面的多态的好处,可以看到我们可以使用父类的参数代替了某个子类的参数,从而达到程序的扩展!

但是对于某个子类有些独有的功能方法时,此时我们的多态的写法就无法访问子类独有功能了。

具体来瞧瞧?

代码如下:

重新定义下猫的子类:

package com.nz.pojo; /** * 定义猫类继承动物类, * 随之重写里面的吃行为,因为猫也有吃的行为,但是猫喜欢吃罐头 */ public class Cat extends Animal{ public void eat() { System.out.println("小喵咪都喜欢吃鱼罐头!"); } /** * 增加一哥猫咪特有的玩球方法() */ public void playBall() { System.out.println("小喵咪都喜欢小球!"); } }

定义测试类:

package com.nz; import com.nz.pojo.Animal; import com.nz.pojo.Cat; /** * 测试多态的弊端! */ public class Demo3 { public static void main(String[] args) { Animal animal = new Cat(); animal.eat(); animal.playBall();//编译报错,编译看左边,Animal没有这个方法 } }

可以看到动物类和猫类有个共同的eat吃方法,但是呢,猫咪多了个玩球球的方法。而对于动物对象来说,它本身动物类没有玩球球的方法,所以它的编译就直接没有通过了!

那有什么方法解决呢?且看下一章节吧!

引用类型转换

1. 引用类型转换是什么,为什么需要它?

从上面的多态的弊端的案例中,我们可以看到,我们使用动物对象时无法直接访问到猫类中的玩球球方法,这也就是我们之前说的编译看左边,运行看右边。

而在我们使用多态方式调用方法时,首先检查会左边的父类中是否有该方法,如果没有,则编译错误。也就代表着,父类无法调用子类独有的方法。、

所以说,如果编译都错误,更别说运行了。这也是多态给我们带来的一点小困扰,而我们如果想要调用子类特有的方法,必须做向下转型。

2. 向上转型(自动转换)

对于向下转型,我们先来讲解下向上转型的概念吧。

向上转型:

多态本身是子类向父类向上转换(自动转换)的过程,这个过程是默认的。当父类引用指向一个子类对象时,便是向上转型。

对于父类和子类的关系来说,具体来看图说话:

父类相对与子类来说是大范围的类型,Animal是动物类,是父类。而Cat是猫咪类,是子类。

所以对于父类Animal来说,它的范围是比较大的,它包含一切动物,包括猫咪类和小狗类。

所以对于子类类型这种范围小的,我们可以直接自动转型给父类类型的变量。

使用格式:

父类类型 变量名 = new 子类类型(); 如:Animal animal = new Cat(); 相当于有: Animal animal = (Animal) new Cat();

相当于自动帮我们了一个隐形的转换为动物类的一个过程,因为动物本身就包含了猫咪。

3. 向下转型(强制转换)

向上转型可以知道它是子类自动转换为父类的一个过程,所以我们现在再来看看向下转型的定义:

向下转型:

向下转型就是由父类向子类向下转换的过程,这个过程是强制的。一个需要将父类对象转为子类对象,可以使用强制类型转换的格式,这便是向下转型。

为什么这种就必须自己强制加上一个类型转换过程呢?

对于父类和子类的关系来说,我们接着看图说话:

对于猫咪类的话,它在动物类中只是其中的一部分吧,而对于动物类来说,它有许多其他子类动物如狗,牛,猪等等。

所以对于动物父类想要向下转型的时候, 它此时不知道指向那个子类,因为不确定呀,所以就必须自己加上强制的类型转换的一个过程。

使用格式:

子类类型 变量名 = (子类类型) 父类变量名; 如: Animal animal = new Cat(); Cat cat = (Cat) animal; cat.playBall();// 此时我们就可以使用猫咪的特有方法啦

所以对于多态的弊端,无法使用子类特有的参数,我们也解决啦,可以通过向下转型的方法,从而将类型强制转换为某个子类对象后,再去调用子类的特有方法!

4. 向下转型的问题

虽然我们可以使用向下转型使得我们可以使用子类的独有方法,但是转型的过程中,一不小心就会遇到这样的问题了,来,我们来看看下面的代码:

public class Test { public static void main(String[] args) { // 向上转型 Animal a = new Cat(); a.eat(); // 调用的是 Cat 的 eat // 向下转型 Dog d = (Dog)a; d.watchHouse(); // 调用的是 Dog 的 watchHouse 【运行报错】 } }

这段代码可以通过编译,但是运行时,却报出了 ClassCastException ,类型转换异常!这是因为,明明创建了Cat类型对象,运行时,当然不能转换成Dog对象的。

5. 转型的异常

转型的过程中,一不小心就会遇到这样的问题,请看如下代码:

定义狗类中额外的独有遛狗方法:

package com.nz.pojo; /** * 定义狗类继承动物类, * 随之重写里面的吃行为,因为狗也有吃的行为,但是狗喜欢啃骨头 */ public class Dog extends Animal{ public void eat() { System.out.println("小狗狗都爱啃骨头!"); } public void walk() { System.out.println("小狗在被我溜着!"); } }

定义测试类

package com.nz; import com.nz.pojo.Animal; import com.nz.pojo.Cat; import com.nz.pojo.Dog; /** * 测试多态的向下转型的问题 */ public class Demo4 { public static void main(String[] args) { // 向上转型的过程 Animal animal = new Cat(); // 调用了猫咪的吃方法 animal.eat(); // 向下转型 Dog dog = (Dog) animal; dog.walk(); // 调用的是 Dog 的 walk 可以通过,但是会运行报错 } }

得到结果:

小喵咪都喜欢吃鱼罐头!

Exception in thread "main" java.lang.classCastException: com.nz.pojo.Cat cannot be cast to com.nz.pojo.Dog

at com.nz.Demo4.main(Demo4.java:20)

我们可以看到,虽然我们的代码通过编译,但是终究在运行时,还是出错了,抛出了 ClassCastException 类型转换的异常。

其实我们可以知道,我们在上面的时候,创建了Cat类型对象,而在向下转型时,将其强行转换为了Dog类型,所以程序在运行时,就会抛出类型转换的异常!

那我们如何可以避免这种异常发生呢?且看下一节分析!

6. instanceof关键字

Java为我们提供一个关键字instanceof ,它可以帮助我们避免了ClassCastException 类型转换异常的发生。

那如何做呢?

格式:

变量名 instanceof 数据类型

解释:

如果变量属于该数据类型或者其子类类型,返回true。

如果变量不属于该数据类型或者其子类类型,返回false。

代码实现:

package com.nz; import com.nz.pojo.Animal; import com.nz.pojo.Cat; import com.nz.pojo.Dog; /** * 使用instanceof解决类型转换异常! */ public class Demo5 { public static void main(String[] args) { // 向上转型的过程 Animal animal = new Cat(); // 调用了猫咪的吃方法 animal.eat(); // 向下转型 if (animal instanceof Cat){ Cat cat = (Cat) animal; cat.playBall(); // 调用的是 Cat 的 playBall } else if (animal instanceof Dog){ Dog dog = (Dog) animal; dog.walk(); // 调用的是 Dog 的 walk } } }

结果:

小喵咪都喜欢吃鱼罐头!

小喵咪都喜欢小球!

可以发现,它可以帮助我们在做类型转换前,判断该类型是否属于该类型或者子类类型,如果是,我们就可以强转啦!

总结

相信各位看官都对Java中的特性之一多态的知识和使用有了一定了解,等待下一次更多Java基础的学习吧!

本篇文章就到这里了,希望能给你带来帮助,也希望您能够多多关注小编的更多内容!

一篇文章带你了解Java基础-接口

一篇文章带你了解Java基础-接口

这篇文章主要介绍了java接口基础知识,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

目录

Java基础知识(接口)

接口

接口的定义

接口和抽象的区别

接口的格式

接口中的主要成分

接口的案例

接口与接口的关系

JDK 8之后的接口新增方法

总结

Java基础知识(接口)

接口

Java接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。

接口的定义

接口:

在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。而接口是更加彻底的抽象,接口中全部是抽象方法。(JDK8之前),接口同样是不能创建对象的。

并且为了弥补我们之前继承中只能单继承的缺点,Java为了我们提供了接口,它可以多实现接口。

接口更像是表达一种能力规范,就想之前我们定义动物,动物有吃的行为方法,而其他实现了动物接口类的动物都必须实现吃这一行为方法。所以其作用主要告诉实现类,你要实现我里面所具备的功能。

那么接口和抽象有什么区别吗?

接口和抽象的区别

抽象类中的方法可以有方法体,就是能实现方法的具体功能,但是接口中的方法不行。

抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是 public static final 类型的。

接口中不能含有静态代码块以及静态方法(用 static 修饰的方法),而抽象类是可以有静态代码块和静态方法。

一个类只能继承一个抽象类,而一个类却可以实现多个接口。

注意:

JDK 1.8 以后,接口里可以有静态方法和方法体了,接口允许包含具体实现的方法,该方法称为默认方法,默认方法使用 default 关键字修饰。

具体的学习,我们一起来看看吧!

接口的格式

主要通过interface关键字修饰在类上,使其成为一个接口类!接口中的所有方法都必须只声明方法标识,而不要去声明具体的方法体。

//接口的格式: 修饰符 interface 接口名称{ // 抽象方法 void eat(); }

而如果类需要去实现该接口的关键字implements。

实现的过程需注意的点:

必须重写实现的全部接口中所有抽象方法。

如果一个类实现了接口,但是没有重写完全部接口的全部抽象方法,这个类也必须定义成抽象类。

//实现接口的格式: 修饰符 class 类名 implements 接口名 { // 实现接口中的所有抽象方法 void eat(){} } // 多实现的格式: 修饰符 class 类名 implements 接口1,接口2,接口3...{ // 抽象方法 void eat(); .... }

接口中的主要成分

我们这里先讲述在JDK8之前,接口中的成分包含:抽象方法和常量

抽象方法:

接口中的抽象方法默认会自动加上public abstract修饰程序员无需自己手写!!

按照规范:以后接口中的抽象方法建议不要写上public abstract,为什么呢?因为没有必要啊,默认会加上。

package src.com.na.pojo; /** * 先定义一个接口父类 --> 动物类 * 动物都有一个吃的抽象方法 */ public interface Animal { // 定义为抽象方法后,无需去做方法实体的实现! // 默认修饰符就是public abstract 可以忽略不写! // public abstract void eat(); // 这种写法也可以,默认忽略了public abstract void eat(); }

常量:

在接口中,我们定义的成员变量默认会加上: public static final修饰。

这代表了什么,在接口中定义的成员变量实际上是一个常量,而我们知道被final关键字修饰的变量是不可被修改,并且也被static静态化修饰了变量,这意味着我们可以直接用接口名访问。

而我们在定义成员变量即常量必须要给初始值。

package src.com.na.pojo; /** * 先定义一个接口父类 --> 动物类 * 动物都有一个吃的抽象方法 */ public interface Animal { // 定义成员变量是常量 // 默认修饰符就是public static final 可以忽略不写! // public static final String NAME = "动物"; String NAME = "动物"; }

注意:常量命名规范建议字母全部大写,多个单词用下划线连接。即ANIMAL_NAME

接口的案例

我们这次以运动员为例吧,这苏神,看得我心血来潮,这不比什么博人传、奥特曼来的热血多了吗。

定义运动员接口

package src.com.na.pojo; /** * 定义一个运动员接口类,运动员可以分很多种:比如田径运动员,举重运动员,乒乓球运动员等。 * 定义了这些运动员之间的一些规范。 */ public interface SportMan { // 例如:运动员,都可以运动,都有对应的项目吧 void project(); // 运动员都会有比赛成绩,结果吧。 void performance(); // 运动员都会参加什么比赛得到什么奖吧,排在第几位吧! String competition(String project); }

定义田径运动员子类去实现运动员接口

package src.com.na.pojo; /** * 定义一个田径运动员,苏神 yyds! 9.83s */ public class AthleticsMan implements SportMan{ /* 实现接口后,必须重写里面的所有抽象方法!!! */ @Override public void project() { System.out.println("苏神参加了奥运会100米项目!!"); } @Override public void performance() { System.out.println("苏神创造了历史,代表亚洲人可以冲进100米决赛,踏进决赛!并创造了亚洲记录9.83s!!!!"); } @Override public String competition(String project) { return "苏炳添参加"+project+"得到第六名!yyds!!!"; } }

定义测试类:

package src.com.na; import src.com.na.pojo.AthleticsMan; /** * 测试接口 */ public class Demo { public static void main(String[] args) { AthleticsMan suBingTian = new AthleticsMan(); suBingTian.project(); suBingTian.performance(); System.out.println(suBingTian.competition("100米")); } }

结果:

苏神参加了奥运会100米项目!!

苏神创造了历史,代表亚洲人可以冲进100米决赛,踏进决赛!并创造了亚洲记录9.83s!!!!

苏炳添参加100米得到第六名!yyds!!!

接口与接口的关系

我们知道类与类之间可以有继承关系,而我们接口与类之间是实现关系,那么接口与接口之间的关系呢?

在Java中,接口与接口之间是可以多继承的:也就是一个接口可以同时继承多个接口。相当于在继承中,将其他接口其他接口的抽象方法与本接口进行了合并。

代码如下:

package src.com.na; public class Demo2 { } // run接口 interface Run{ void run(); } interface Project{ void Project(); } /* * 总结: * 接口与类之间是多实现的。 * 接口与接口之间是多继承的。 * */ interface SportMan2 extends Run , Project { String competition(String project); // 抽象方法,比赛。 }

JDK 8之后的接口新增方法

在JDK 8开始之后,接口似乎变得不再纯洁了!

接口中不再只是抽象方法,接口还可以有默认方法(也就是实例方法),和静态方法了,还包含了私有实例方法和私有静态方法

1. 含有默认方法和静态方法

默认方法:使用 default 修饰,不可省略,供子类调用或者子类重写。

静态方法:使用 static 修饰,供接口直接调用。

代码如下:

package src.com.na.pojo; /** * 测试接口中可以含有默认方法和静态方法 */ public interface InterfaceTest { // 含有默认方法,default关键字 public default void defaultMethod() { System.out.println("默认方法"); } // 含有静态方法,static关键字 public static void staticmethod() { System.out.println("静态方法"); } }

2. 含有私有方法和私有静态方法

私有方法:使用 private 修饰,供接口中的默认方法或者静态方法调用。

私有静态方法:使用 private 修饰,使用 static 修饰。

代码如下:

package src.com.na.pojo; /** * 测试接口中可以含有私有方法和私有静态方法 */ public interface InterfaceTest2 { // 含有私有方法,private修饰 private void privateMethod() { System.out.println("私有方法"); } // 含有私有静态方法,static关键字,private修饰 private static void privateStaticmethod() { System.out.println("私有静态方法"); } }

接口的特点:

接口中的方法全是抽象方法,默认会自动加上public abstract修饰。

接口中,无法定义成员变量,但是可以定义常量,其值不可以改变,默认使用public static final修饰。

接口中,没有构造器,所以是不能创建对象滴!

类与接口之间的关系是多实现的。

接口与接口之间关系是多继承的。

接口更多体现的是一种规范。

JDK 8开始,接口不再纯洁,支持静态方法,默认方法,私有方法。

总结

相信各位看官都对Java基础中的抽象和接口的知识和使用有了一定了解,等待下一次更多Java基础的学习吧!

一篇文章带你入门Java修饰符

一篇文章带你入门Java修饰符

Java语言提供了很多修饰符,主要分为以下两类:访问修饰符;非访问修饰符。修饰符用来定义类、方法或者变量,通常放在语句的最前端。我们通过下面的例子来说明,下面就跟小编一起来看下吧

目录

定义

分类

访问控制修饰符

非访问控制修饰符

修饰符的使用说明

修饰类

修饰方法

访问控制修饰符

非访问控制修饰符

修饰变量

总结

定义

Java修饰符:修饰符用来定义类、方法或者变量,通常放在语句的最前端。

分类

主要分为2类:

访问控制修饰符

非访问控制修饰符

访问控制修饰符

可以使用访问控制符来保护对类、变量、方法和构造方法的访问。分为以下4中权限:private,default,protected,public。

权限说明:

修饰符

当前类

同包

子类(不同包)

不同包(其他类)

private

Y

default

Y

Y

protected

Y

Y

Y

public

Y

Y

Y

Y

非访问控制修饰符

修饰符

说明

static

用来修饰类方法和类变量。

final

用来修饰类、方法和变量,final 修饰的类不能够被继承,修饰的方法不能被继承类重新定义,修饰的变量为常量,是不可修改的。

abstract

用来创建抽象类和抽象方法。

synchronized

volatile

主要用于线程的编程。

修饰符的使用说明

修饰类

1.public 将一个类声明为公共类,他可以被任何对象访问,一个程序的主类必须是公共类,一个.java文件中只能有一个public类,而且文件名必须与该类相同。

public class Learn9 { public static void main(String[] args) { } }

假如类名与文件名不一致

如果一个 .java 文件中两个public类呢?

报错跟刚才一样,就是公共类必须独立占用一个java文件。

1.把下面修饰类的public去掉就可以了。

♀ 小AD:明哥,我有个问题?

♂ 明世隐:请放!

♀ 小AD:文明点啊哥,就知道欺负人家,我就想说这一个类里面怎么还可以再放一个类的,也没看到报错。

♂ 明世隐:这个是可以的,就比如我可以带你双排、三排、5排,甚至可以。。。,但是你必须搞清楚谁是大哥,谁是小老弟。

♀ 小AD:哥我知道,你就是那个大哥,只有你可以抛头露面、带头冲锋,用public修饰。

♂ 明世隐:算你识相,不然我单排去了。

♀ 小AD:是是是,哥回头请你吃奶茶!

♂ 明世隐:说谎的人要吞一千根针哦。

♀ 小AD:。。。

♂ 明世隐:一般也不这样写,写成单独的普通类,这种内部类写法主要是一个功能模块的方便或者相关的封装。

♂ 明世隐:其实他们虽然放在一起,也只是编译时概念,编译完成后也是独立的class文件。

♀ 小AD:哦

♂ 明世隐:就比如刚才写的代码

2.默认的,把一个类声明为默认的,可以被同一个包中的其他类使用。

3.abstract,将一个类声明为抽象类,抽象类中可以有抽象方法,也可以没有。抽象类只能被继承不能被实例化。

4.final,将一个类声明为最终(即非继承类),表示他不能被其他类继承。

5.外部类不能使用protected、private、static等修饰符,内部类可以使用。

♀ 小AD:我开始懵逼了。

♂ 明世隐:很正常,因为抽象类、最终类的你都没接触过,不过不要紧,你现阶段只要有个印象,不需要去记,后面单独再讲这个,你只需要知道public修饰类就行了。

♀ 小AD:好,这样就比较好弄。

修饰方法

访问控制修饰符

1.private

在Learn10类中创建私有方法test

private void test() { System.out.println("learn10 test方法被调用"); }

主方法main 调用这个方法

public class Learn10 { public static void main(String[] args) { System.out.println("learn10 main"); new Learn10().test(); } private void test() { System.out.println("learn10 test方法被调用"); } }

运行

在同包下的 Learn9 类看能否调用此方法

同包下的类都不能调用private了,更别说其他包了。

2.default

把Learn10类中创建方法test改成默认的,也就是把private删除

public class Learn10 { public static void main(String[] args) { System.out.println("learn10 main"); new Learn10().test(); } void test() { System.out.println("learn10 test方法被调用"); } }

public class Learn9 { public static void main(String[] args) { System.out.println("learn9 main"); new Learn10().test(); } }

可以看到本类和同包下的类可以访问的,其他包的试一下。

建立包adc,并创建类XiaoLuBan,调用test方法:

3.protected

把Learn10类中创建方法test改成protected的,然后发现跟上面的是一样的,其他包中也不行,但实际上这个在子类中是可以的,子类的问题下次再研究。4.public方法修饰改成publicpublic class Learn10 { public static void main(String[] args) { System.out.println("learn10 main"); new Learn10().test(); } public void test() { System.out.println("learn10 test方法被调用"); } }public class Learn9 { public static void main(String[] args) { System.out.println("learn9 main"); new Learn10().test(); } }import learnJava.Learn10; public class XiaoLuBan { public static void main(String[] args) { new Learn10().test(); } }发现public是都可以用。♀ 小AD:明哥,是不是又只要记住public。♂ 明世隐:对,public确实很常用,但是private也蛮经常用。♀ 小AD:是不是跟排位排队一样的,没排到之前大家都可能排到,公共的。♂ 明世隐:你咋啥都要往这方面想?♀ 小AD:没办法,我天生丽质。private就是比如我两双排,固定组合,总不能把你T出去,我跟别人排吧。♂ 明世隐:你这么一说,我瞬间觉得以前我学代码的时候,不香了。♀ 小AD:那可不,我是人见人爱、花见花。。。♂ 明世隐:花见花凋零!

非访问控制修饰符

1.抽象方法控制符abstractabstract 修饰的方法称为抽象方法。抽象方法仅有方法头,没有方法体和具体实现。2.静态方法控制符static指定不需要实例化就可以调用的一个方法,即在内存中只有一份,通过类名即可调用。3.最终方法控制符final最终方法是功能和内部语句不能更改的方法,即最终方法不能重写覆盖。4.本地方法控制符native指定此方法的方法体是用其他语言在程序外部编写的。5.同步方法控制符synchronized同步修饰符,在多个线程中,该修饰符用于在运行前,对它所属的方法加锁,以防止其他线程的访问,运行结束后解锁。♂ 明世隐:abstract等后面讲接口的时候来说明,我们比较常用就是 static 了。♀ 小AD:这个我知道,main方法就是用static修饰的。♂ 明世隐:用static修饰的调用就不需要每次都实例化,可以直接调用。♀ 小AD:为啥不用实例化,我之前看你的调用方法都是要 new *** 这样的 。♂ 明世隐:嗯,new 类名 就是实例化,static 方法在类第一次加载的时候,static就已经在内存中了,直到程序结束后,该内存才会释放。不需要再消耗资源反复创建对象。♀ 小AD:我觉得我听懂了。♂ 明世隐:那你说说看♀ 小AD:比如我们两双排,你邀请我后,每盘结束以后是不是不需要重新再拉我了,默认就在队伍里面,不需要你每次点击邀请,重复力气。(符合两个条件:1.第一次就加载。2.不需要重复占用资源。)♂ 明世隐:我草,给我个痛快吧,受不了了。♀ 小AD:我这才学多久你就受不了了。♂ 明世隐:我只能说你是大聪明!♀ 小AD:哥,我肯定你是在夸我。♂ 明世隐:对对对!看一下static调用实例。public class Learn9 { public static void main(String[] args) { System.out.println("learn9 main"); Learn9.test(); } static void test(){ System.out.println("learn9 static test"); } }运行

修饰变量

1.public(公共访问控制符),指定该变量为公共的,它可以被任何对象的方法访问。定义public变量a,看看访问情况在同类中public class Learn10 { public int a=10; public static void main(String[] args) { System.out.println("learn10 main"); new Learn10().test(); } void test(){ System.out.println(a); } }同包别的类public class Learn9 { public static void main(String[] args) { System.out.println("learn9 main"); System.out.println(new Learn10().a ); } }不同包中import learnJava.Learn10; public class XiaoLuBan { public static void main(String[] args) { System.out.println(new Learn10().a ); } }可以看到都是可以访问的。2.protected(保护访问控制符)指定该变量可以别被自己的类和子类访问。在子类中可以覆盖此变量。把变量a改成 protected

可以观察到在其他包中不能访问到3.default(默认权限),指定该变量只对同包可见,对不同包(含不同包的子类)不可见。改成default,和上面的情况一样(子类的情况先不管)4.private(私有访问控制符)指定该变量只允许自己的类的方法访问,其他任何类(包括子类)中的方法均不能访问。

改成private后只有本类中的方法可以访问到这个变量。5.final,最终修饰符,指定此变量的值不能变。把a定义成final后,想对这个变量进行赋值操作,就会编译错误。

6.static(静态修饰符)指定变量被所有对象共享,即所有实例都可以使用该变量。变量属于这个类。♀ 小AD:明哥这次还是要重点关注public咯♂ 明世隐:额。。不要一概而论,变量常用private修饰符。♀ 小AD:那不是只能在本类中才能访问吗?我其他类调用怎么办?♂ 明世隐:你知道private只能在本类中访问,说明private你是熟悉了。♀ 小AD:对啊 ,那怎么取这个变量呢?♂ 明世隐:用set get方法来存取呢。♀ 小AD:那你还不是要把set get方法设置成public的吗?有嘛区别?多此一举。♂ 明世隐:你有此问题,说明你是个爱动脑的娃儿,但是你段位怎么就上不去了呢?♀ 小AD:哥,你咋回事绕到那边去了。♂ 明世隐:意思就是说,我们一般不能直接开放给别人访问变量,通过set get 访问更安全,我们可以在set get方法中做相应的修饰,就不会被随意的设置上值了。实例1:直接修改属性方式public class XiaoLuBan { private String yanzhi = ""; public static void main(String[] args) { XiaoLuBan xiaoLuBan = new XiaoLuBan(); xiaoLuBan.yanzhi="丑八怪"; System.out.println(xiaoLuBan.niDeYanZhi()); } public String niDeYanZhi(){ return yanzhi; } }

实例2:通过set方式public class XiaoLuBan { private String yanzhi = ""; public static void main(String[] args) { XiaoLuBan xiaoLuBan = new XiaoLuBan(); //xiaoLuBan.yanzhi="丑八怪"; xiaoLuBan.setYanzhi("丑八怪"); System.out.println(xiaoLuBan.niDeYanZhi()); } public void setYanzhi(String yanzhi) { if("美女".equals(yanzhi)){ this.yanzhi = yanzhi; }else if("五百年一遇的美女".equals(yanzhi)){ this.yanzhi = yanzhi; }else{ this.yanzhi = "大美女"; } } public String niDeYanZhi(){ return yanzhi; } }

♀ 小AD:原来是这样啊,直接设置比较死板,还容易有问题。♂ 明世隐:对啊,所以推荐set get方法来使用变量,变量设置为private。♀ 小AD:比如你的钱,是私有的,如果设置为public的,那我可以拿了吧。♂ 明世隐:你想的美,你问你嫂子拿去吧,我创建一个方法,通过你嫂子拿。♀ 小AD:我怕我要被打。♂ 明世隐:知道就好!哥给你展示一下怎么用。/** * 明哥类 * */ public class MingGe { private int money=10000000; public void getMoneyFromMingSao(String user) { System.out.println("明哥的资产:"+money); if("明哥".equals(user)){//如果是明哥,给1000 money-=1000; System.out.println("1000"); }else if("小鲁班".equals(user)){//如果是小鲁班,找打 System.out.println("找打吧你"); }else{ System.out.println("给你 0 元"); } System.out.println("取钱后明哥的资产:"+money); } public static void main(String[] args) { new MingGe().getMoneyFromMingSao("明哥"); } }

public class MingGe { private int money=10000000; public void getMoneyFromMingSao(String user) { System.out.println("明哥的资产:"+money); if("明哥".equals(user)){//如果是明哥,给1000 money-=1000; System.out.println("1000"); }else if("小鲁班".equals(user)){//如果是小鲁班,找打 System.out.println("找打吧你"); }else{ System.out.println("给你 0 元"); } System.out.println("取钱后明哥的资产:"+money); } public static void main(String[] args) { //new MingGe().getMoneyFromMingSao("明哥"); new MingGe().getMoneyFromMingSao("小鲁班"); } }

@H_134_301@

♀ 小AD:明哥,你在家里的地位有那么高吗?我才不信♂ 明世隐:你不看哥我是谁,哥拿捏的好。♀ 小AD:切。。。,打排位还不让嫂子知道,还说你拿捏的好。♂ 明世隐:你不是一样吗,还说这个,今天你的星就免了,拜拜了您嘞。♀ 小AD:不是哥、哎、哥。。。。。。哥。

总结

本篇文章就到这里了,希望能给你带来帮助,也希望您能够多多关注小编的更多内容!

一篇文章带你入门Java基本概念

一篇文章带你入门Java基本概念

本文主要介绍了Java编程的基本概念基本概念,可以帮助我们更加深刻的所要讲解的Java命令,具有很好的参考价值。下面跟着小编一起来看下吧,希望能给你带来帮助

目录

Java基本概念

一、JRE(Java运行时环境)

二、JDK(Java开发工具)

三、Java源代码文件(.class)

四、Java字节码文件(.java)

五、Java虚拟机(JVM)

六、跨平台运行

七、JDK与JRE、JVM的关系?

八、几个结论

总结

Java基本概念

JDK包含了不少Java开发相关命令。如,javac、java、javap、javaw、javadoc。虽然现在的Java开发都使用IDE完成,基本上不会直接使用这些命令。但是理解这些命令的用法,可以让我们更加扎实的掌握java编译、运行等的基本概念。

在讲解Java命令之前,我们先了解一些基本概念,可以帮助我们更加深刻的所要讲解的Java命令。

一、JRE(Java运行时环境)

Java Runtime Environment。故名思意,包含了运行Java程序所需的环境,比如Java虚拟机、相关的类库等相关资源。**你可以将JRE理解成一个运行在操作系统上的程序,该程序可以用来运行Java程序。**这个程序只用来运行运行Java程序,但并不包含Java开发的工具。因此,对于开发人员,只有JRE是不够。对于需要运行的Java程序的普通用户,只需要正确版本的JRE就可以运行Java程序了。

注意:每个操作系统上的JRE程序都是不一样的,比如Windows与Linux上的JRE就不一样。你可以将不一样,理解成他们的代码不同。因此你在下载时,会发现不同操作操作系统会有不同的JRE,即使是同一个操作系统,32位与64位的JRE也不一样。

二、JDK(Java开发工具)

Java Development Kit。包含了Java开发的工具,比如javac、javap命令、java源代码等。对于开发人员,需要下载这个才能开发Java程序。

JDK 8及之前,安装JDK的时候除了安装JDK还会安装一个独立的JRE,因此你在安装的时候,会发现要安装两个东西。这个JRE,可以运行兼容版本的Java程序。换句话说,对于所有Java程序,某个JRE是完全一样的,不能单独定制。注意:安装JDK 8实际上安装了两个JRE。一个安装在JDK目录的jre目录中,另一个安装在你指定的其他目录。

JDK 11及之后,不包含另一个独立的JRE。JDK本身已经包含了Java的运行时环境,不过这个运行时环境剥离了一些东西,比如默认不包含的Java Swing。Java 11使用了jigsaw模块化系统,你可以为java程序创建一个更小的适合该程序的JRE。比如,你的Java程序不包含Java Swing代码,你可以使用jlink为你的程序定制一个更小的专属于你的程序的JRE。

结论:

1.JDK 11后,你不需要安装独立的JRE,因为其已经包含了。

2.JDK 11引入了模块化系统,你可以为自己的程序定制JRE。

三、Java源代码文件(.class)

.java文件(后缀名为java,如Hello.java),包含Java源代码。本质上是一个文本文件,可通过文本编辑器编辑,不能直接运行。

四、Java字节码文件(.java)

.class文件(如Hello.class),.java文件经过javac命令编译得到.class文件。是一个二进制文件,包含了Java虚拟机才看得懂的字节码命令。

五、Java虚拟机(JVM)

Java Virtual Machine,简称JVM。通常来说JRE都要包含JVM。JVM是字节码文件运行的环境,可以加载与运行java类。你的.class实际上是跑在JVM上,而JVM则是一个独立的程序,运行在操作系统上。每个操作系统上JVM的程序都不一样。但他们有一个共同之处,就是都可以运行你的.class文件。

六、跨平台运行

什么是跨平台运行呢?

就是你编写好的.java源代码编译为.class字节码文件后,那么任何兼容该.class文件的JRE中的JVM都可以运行该字节码文件。而无需考虑这个JRE到底是Linux下的,还是Windows下。简单地说,你在Windows下编译好的.class文件,拿到Linux下,只要JRE版本正确,就可以运行。注意:这里的兼容指的是,Java版本的向下兼容。比如,你在Java 8下编译的字节码文件,理论上来说Java 11是可以直接运行的。反之则不行。

相比较于C或C++语言,你在Windows下使用gcc工具编译、链接成可执行程序.exe。这个可执行程序,在Linux下是无法执行的。

为什么可以跨平台呢?

关键在于JVM。.class字节码文件是结构中立的。所谓的结构中立指的是.class文件包含的面向JVM的字节码命令,而不是面对某个操作系统的机器码。你在哪个操作系统上对某个.java文件进行编译生成的.class文件都是一样的(只要Java版本相同)。因此,不管你是Linux上的JVM还是Windows上的JVM,都可以运行这些.class文件中字节码指令。见下图。

注意:字节码不是机器码,因此不能直接在操作系统上直接运行。只能先运行JVM,才能运行字节码文件。这也就是早期Java程序慢的一个原因。

七、JDK与JRE、JVM的关系?

JDK包含了JRE与Java开发工具(如javac,java,jar, jlink等命令)。

JRE包含了JVM、java类库与一些资源文件。

八、几个结论

1.Java程序的开发运行流程

编写.java文件―经过javac编译―>.class文件―使用java命令载入―>载入到JVM运行。

如下图所示。

2.运行JAVA程序必须先运行JRE中的JVM。

3.Java程序是跨平台的。编译好的.class文件可以在不同操作系统上兼容的Java上运行。

4.Java 11及以后支持模块化系统jigsaw。因此可为自己的Java程序定制化JRE。不过初学者,暂时不用考虑这些,直接使用默认的JRE即可。但碰到问题时(如要编写Java Swing程序,却提示错误),要了解问题可能产生的原因。

总结

本篇文章就到这里了,希望能给你带来帮助,也希望您能够多多关注小编的更多内容!

关于一篇文章带你搞定JAVA注解一篇文章带你搞定java注解的软件的问题我们已经讲解完毕,感谢您的阅读,如果还想了解更多关于一篇文章带你了解Java基础-多态、一篇文章带你了解Java基础-接口、一篇文章带你入门Java修饰符、一篇文章带你入门Java基本概念等相关内容,可以在本站寻找。

本文标签: