带你入门Java的泛型

目录
  • 泛型
    • 1、简单泛型
      • (1)元组
      • (2)堆栈
    • 2、泛型接口
    • 3、泛型方法
      • (1)类型推断
      • (2)通用的Generator
      • (3)Set实用工具实现数学方法
    • 4、擦除
      • (1)迁移兼容性
      • (2)擦除的问题
    • 5、擦除的补偿
      • (1)由于擦除原因,无法通过instanceof比较类型。如果引入类型标签,就可以转而使用动态的isInstance()。
      • (2)创建类型实例
      • (3)泛型数组
    • 6、边界
    • 7、通配符
      • (1)List<? extends Fruit>协变
      • (2)List<? super Fruit>逆变
      • (3)无界通配符List<?>
      • (4)捕获转换
    • 8、问题
      • (1)任何基本类型都不能作为类型参数
      • (2)实现参数化接口
      • (3)转型和警告
      • (4)重载
      • (5)基类劫持了接口
    • 9、自限定
    • 10、异常
  • 总结

泛型

1、简单泛型

泛型的主要目的之一就是用来指定容器要持有什么类型的对象,而且由编译器来保证类型的正确性。

泛型暂时不指定类型,在使用时决定具体使用什么类型。通过<T>来实现,T就是类型参数。

(1)元组

class TwoTuple<A,B>{
    public final A first;
    public final B second;
    public TwoTuple(A a,B b){
        first = a;
        second = b;
    }
​
    @Override
    public String toString() {
        return "{ " + first +
                ", " + second +
                '}';
    }
}

(2)堆栈

class LinkedStack<T>{
    private class Node {
        T item;
        Node next;
        Node() { item = null; next = null; }
        Node(T item, Node next) {
            this.item = item;
            this.next = next;
        }
        boolean end() { return item == null && next == null; }
    }
​
    private Node top = new Node();
    public void push(T item) { top = new Node(item, top); }
    public T pop() {
        T result = top.item;
        if(!top.end())
            top = top.next;
        return result;
    }
}
(3)RandomList
class RandomList<T>{
    private ArrayList<T> storage = new ArrayList<>();
    private Random rand = new Random(47);
    public void add(T item){
        storage.add(item);
    }
    public T select(){
        return storage.get(rand.nextInt(storage.size()));
    }
}

2、泛型接口

泛型也可以应用于接口,例如生成器,这是一种专门负责创建对象的类。

import net.mindview.util.Generator;
import java.util.Iterator;
​
class Fibonacci implements Generator<Integer> {
    private int count = 0;
    public Integer next(){
        return fib(count++);
    }
    private int fib(int n){
        if(n<2) return 1;
        return fib(n-2) + fib(n-1);
    }
}
​
class IterableFibonacci implements Iterable<Integer> {
    private Fibonacci fib = new Fibonacci();
    private int n;
    public IterableFibonacci(int count){
        n = count;
    }
​
    @Override
    public Iterator<Integer> iterator() {
        return new Iterator<Integer>() {
            @Override
            public boolean hasNext() {
                return n>0;
            }
​
            @Override
            public Integer next() {
                n--;
                return fib.next();
            }
            public void remove() { // Not implemented
                throw new UnsupportedOperationException();
            }
        };
    }
}

3、泛型方法

  泛型方法使得该方法能够独立于类而产生变化。使用泛型方法的时候,通常不必指明参数类型,因为编译器会为我们找出具体的类型,这称为类型参数推断。

 class GenericMethods{
     public <T> void f(T x){
      System.out.println(x.getClass().getSimpleName());
     }
}

(1)类型推断

  使用泛型有时候需要向程序中加入更多的代码。如下所示:

 Map<Person,List<? extends Pet>> petPerson =
     new HashMap<Person,List<? extends Pet>>();

在泛型方法中可以通过类型推断来简化一部分工作。如下所示:

class New{
    public static <K,V> Map<K,V> map(){
        return new HashMap<K,V>();
    }
​
    public static void main(String[] args) {
        Map<Person,List<? extends Pet>> petPerson = New.map();
    }
}

类型推断只对赋值操作有效,其他时候并不起作用。如果将一个泛型方法的结果作为参数,传递给另一个方法时,另一个方法需要显式的类型说明。如下所示:

public class ExplicitTypeSpecification{
    static void f(Map<Person,List<? extends Pet>> petPerson){}
    public static void main(String[] args) {
        f(New.<Person,List<? extends Pet>>map());
    }
}

(2)通用的Generator

import net.mindview.util.Generator;
​
public class BasicGenerator<T> implements Generator<T>{
    private Class<T> type;
    public BasicGenerator(Class<T> type){
        this.type = type;
    }
    public T next(){
        try {
            return type.newInstance();
        }catch (Exception e){
            throw new RuntimeException(e);
        }
    }
    public static <T> Generator<T> create(Class<T> type){
        return new BasicGenerator<T>(type);
    }
}

(3)Set实用工具实现数学方法

public class Sets{
    @SuppressWarnings("unchecked")
    protected static <T> Set<T> copy(Set<T> s) {
        if(s instanceof EnumSet)
            return ((EnumSet)s).clone();
        return new HashSet<T>(s);
    }
​
    //并集
    public static <T> Set<T> union(Set<T> a, Set<T> b) {
        Set<T> result = copy(a);
        result.addAll(b);
        return result;
    }
    //交集
    public static <T> Set<T> intersection(Set<T> a, Set<T> b) {
        Set<T> result = copy(a);
        result.retainAll(b);
        return result;
    }
    //差集
    public static <T> Set<T> difference(Set<T> superset, Set<T> subset) {
        Set<T> result = copy(superset);
        result.removeAll(subset);
        return result;
    }
    //包含除了交集以外的所有元素
    public static <T> Set<T> complement(Set<T> a, Set<T> b) {
        return difference(union(a, b), intersection(a, b));
    }
}

4、擦除

Java泛型是使用擦除来实现的,这意味着当你在使用泛型时,任何具体的类型信息都被擦除了,你唯一知道的就是你在使用一个对象。因此List<String>和List<Integer>在运行时事实上是相同的类型,都被擦除成它们的“原生”类型List。

(1)迁移兼容性

泛型类型只有在静态类型检查期间才出现,在此之后,程序中的所有泛型类型都将被擦除,替换为他们的非泛型上界。擦除的核心动机是它使得泛化的客户端可以用非泛化的类库来使用,反之亦然,这经常被称为“迁移兼容性”。

(2)擦除的问题

泛型的所有关于参数的类型信息都丢失了,所以不能用于显式地引用运行时类型的操作之中,例如转型、instanceof操作和new表达式。

5、擦除的补偿

(1)由于擦除原因,无法通过instanceof比较类型。如果引入类型标签,就可以转而使用动态的isInstance()。

public class ClassTypeCapture<T>{
    Class<T> kind;
    public ClassTypeCapture(Class<T> kind){
        this.kind = kind;
    }
    public boolean f(Object arg){
        return kind.isInstance(arg);
    }
}

(2)创建类型实例

通过工厂对象来创建实例。如果使用类型标签,就可以使用newInstance()来创建这个类型的新对象。

class ClassAsFactory<T>{
    T x;
    public ClassAsFactory(Class<T> kind){
        try{
            x = kind.newInstance();
        }catch(Exception e){
            throw new RuntimeException(e);
        }
    }
}

如果类没有默认的构造器,上面的案例会创建失败。为了解决这个问题,可以通过显示的工厂来实现。

interface FactoryI<T>{
    T create();
}
class Foo2<T>{
    private T x;
    public <F extends FactoryI<T>> Foo2(F factory){
        x = factory.create();
    }
}
class IntegerFactory implements FactoryI<Integer>{
    public Integer create(){
        return new Integer(6);
    }
}

另一种方式是模板方法设计模式。

abstract class GenericWithCreate<T>{
    final T element;
    GenericWithCreate(){ element = create(); }
    abstract T create();
}
​
class X{}
​
class Creator extends GenericWithCreate<X>{
    X create(){ return new X(); }
}

(3)泛型数组

无法通过 T[] array = new T[sz] 来创建泛型数组,一般的解决方法是在需要泛型数组的地方都使用ArrayList。

在创建泛型数组时,有以下三种情况:

①创建时强制转型

public class GenericArray<T>{
    private T[] array;
    @SuppressWarnings("unchecked")
    public GenericArray(int sz){
        array = (T[])new Object[sz];
    }
    public T[] rep(){ return array; }
​
    public static void main(String[] args) {
        GenericArray<Integer> gai = new GenericArray<Integer>(10);
        Integer[] ia = gai.rep();//引起ClassCastException
        Object[] oa = gai.rep();
    }
}

②方法返回时强制转型

class GenericArray2<T>{
    private Object[] array;
    @SuppressWarnings("unchecked")
    public GenericArray(int sz){
        array = new Object[sz];
    }
    public T[] rep(){ return (T[])array; }
    public static void main(String[] args) {
        GenericArray<Integer> gai = new GenericArray<Integer>(10);
        Integer[] ia = gai.rep();//引起ClassCastException
        Object[] oa = gai.rep();
    }
}

③使用Array.newInstance()

以上两种方法都无法创建具体类型的数组,无法推翻底层的数组类型,只能是Object[]。通过传入类型标记Class<T>,可以从擦除中恢复。

class GenericArray3<T>{
    private T[] array;
    @SuppressWarnings("unchecked")
    public GenericArray(Class<T> type,int sz){
        array = (T[]) Array.newInstance(type,sz);
    }
    public T[] rep(){ return array; }
    public static void main(String[] args) {
        GenericArray<Integer> gai = new GenericArray<Integer>(Integer.class,10);
        Integer[] ia = gai.rep();//可以正常运行
        Object[] oa = gai.rep();
    }
}

6、边界

边界使得你可以在用于泛型的参数类型上设置限制条件,可以按照自己的边界类型来调用方法。

public class Test {
    public static void main(String[] args) {
        Man m = new Man();
        m.hear();
        m.smell();
    }
}
​
interface SuperPower{}
interface SuperHearing extends SuperPower{
    void hearSubtleNoises();
}
interface SuperSmell extends SuperPower{
    void trackBySmell();
}
​
class SuperHero<POWER extends SuperPower>{
    POWER power;
    SuperHero(POWER power){ this.power = power; }
    POWER getPower(){ return power; }
}
​
class CaineHero<POWER extends SuperHearing & SuperSmell> extends SuperHero<POWER>{
    CaineHero(POWER power){ super(power); }
    void hear(){ power.hearSubtleNoises(); }
    void smell(){ power.trackBySmell(); }
}
​
class SuperHearSmell implements SuperHearing,SuperSmell{
​
    @Override
    public void hearSubtleNoises() {
        System.out.println("hearSubtleNoises");
    }
​
    @Override
    public void trackBySmell() {
        System.out.println("trackBySmell");
    }
}
​
class Man extends CaineHero<SuperHearSmell>{
    Man(){ super(new SuperHearSmell()); }
}

7、通配符

(1)List<? extends Fruit>协变

表示具有任何从Fruit继承的类型的列表。List<? extends Fruit>可以合法地指向一个List<Apple>。一旦执行这种类型的向上转型,就将丢失掉向其中传递任何对象的能力,甚至是传递Object也不行。

List<? extends Fruit> flist =
    Arrays.asList(new Apple());
//Compile Error:can't add any type of object
//add()的参数是<? extends Fruit>,编译器不知道需要Fruit的哪个
//具体的子类型,因此不接受任何类型的Fruit
//flist.add(new Apple());
//flist.add(new Fruit());
//flist.add(new Object());
flist.add(null);//Legal but uninteresting
Apple a = (Apple)flist.get(0);//No warning
Fruit f = flist.get(0);//No warning
flist.contains(new Apple());//参数是Object
flist.indexOf(new Apple());//参数是Object

(2)List<? super Fruit>逆变

超类型通配符可以安全地传递一个类型对象到泛型类型中。List<? super Fruit>意味着向其中添加Fruit或Fruit的子类型是安全的。

List<? super Fruit> flist = new ArrayList<Fruit>();
        flist.add(new Apple());
        flist.add(new Fruit());
//Error:Incompatible Type
//Fruit f = flist.get(0);
Object f = flist.get(0);//OK,but type information has been lost

(3)无界通配符List<?>

List实际上表示“持有任何Object类型的原生List”,List<?>表示“具有某种特定类型的非原生List,只是我们不知道那种类型是什么”,List<? extends Object>表示“类型是Object的导出类”。

无界通配符的一个重要应用:处理多个泛型参数时,允许一个参数可以是任何类型,同时为其他参数确定某种特定类型。

Map<String,?> map = new HashMap<String,Integer>;
map = new HashMap<String,String>;

原生Holder与Holder<?>是大致相同的事物,但存在不同。它们会揭示相同的问题,但是后者将这些问题作为错误而不是警告报告。

static void rawArgs(Holder holder,Object arg){
    //holder.set(arg);
    //Warning:Unchecked call to set(T) as member
    //of the raw type Holder
    //holder.set(new Wildcards());//Same Warning
    //Can't do this:don't have any 'T'
    //T t = holder.get();
    //OK,but type infomation has been lost
    Object obj = holder.get();
}
//Similar to rawArgs(),but errors instead of warnings
static void unboundedArg(Holder<?> holder,Object arg){
    //holder.set(arg);
    //Error:set(capture of ?) in Holder<capture of ?>
    //cannot be applied to (Object)
    //holder.set(new Wildcards());//Same Error
    //Can't do this:don't have any 'T'
    //T t = holder.get();
    //OK,but type infomation has been lost
    Object obj = holder.get();
}

(4)捕获转换

未指定的通配符类型被捕获,并被转换为确切类型。在f2()中调用f1(),参数类型在调用f2()的过程中被捕获,因此它可以在对f1()的调用中被使用。不能从f2()中返回T,因为T对于f2()来说是未知的。

static <T> void f1(Holder<T> holder){
    T t = holder.get();
     System.out.println(t.getClass().getSimpleName());
}
​
static <T> void f2(Holder<T> holder){
    f1(holder);
}

8、问题

(1)任何基本类型都不能作为类型参数

(2)实现参数化接口

一个类不能实现同一个泛型接口的两种变体。将泛型参数移除掉后,这段代码就可以正常编译了。

interface Payable<T>{}
​
class Employee implements Payable<Employee>{}
​
//Compile Error:cannot be inherited with different type arguments
class Hourly extends Employee implements Payable<Hourly>{}

(3)转型和警告

使用带有泛型类型参数的转型或instanceof不会有任何效果。

由于擦除原因,编译器无法知道这个转型是否安全,并且pop()方法实际上并没有执行任何转型。如果没有@SuppressWarnings注解,编译器将对pop()产生“Unchecked cast”警告。

private int index = 0;
private Object[] storage;
@SuppressWarnings("unchecked")
public T pop(){ return (T)storage[--index]; }

(4)重载

由于擦除的原因,重载方法将产生相同的类型签名,导致程序不能编译。

public class UseList<W,T>{
     void f(List<T> v){}
     void f(List<W> v){}
 }

(5)基类劫持了接口

一旦为Comparable确定了ComparablePet参数,那么其他任何实现类都不能与ComparablePet之外的任何对象比较。在前面的“实现参数化接口”章节里面的第一个例子,就体现了基类劫持接口。

public class ComparablePet
implements Comparable<ComparablePet> {
  public int compareTo(ComparablePet arg) {
      return 0;
  }
}
​
class Cat extends ComparablePet implements Comparable<Cat>{
  // Error: Comparable cannot be inherited with
  // different arguments: <Cat> and <Pet>
  public int compareTo(Cat arg) { return 0; }
} ///:~
​
class Hamster extends ComparablePet
    implements Comparable<ComparablePet>{
    public int compareTo(ComparablePet arg) {
        return 0;
    }
}

9、自限定

class Subtype extends BasicHolder<Subtype> {}这样用,就构成自限定了。从定义上来说,它继承的父类的类型参数是它自己。

从使用上来说,Subtype对象本身的类型是Subtype,且Subtype对象继承而来的成员(element)、方法的形参(set方法)、方法的返回值(get方法)也是Subtype了(这就是自限定的重要作用)。这样Subtype对象就只允许和Subtype对象(而不是别的类型的对象)交互了。

class BasicHolder<T> {
    T element;
    void set(T arg) { element = arg; }
    T get() { return element; }
    void f() {
        System.out.println(element.getClass().getSimpleName());
    }
}
​
class Subtype extends BasicHolder<Subtype> {}
​
public class CRGWithBasicHolder {
    public static void main(String[] args) {
        Subtype st1 = new Subtype(), st2 = new Subtype(), st3 = new Subtype();
        st1.set(st2);
        st2.set(st3);
        Subtype st4 = st1.get().get();
        st1.f();
    }
} /* Output:
Subtype
*/

10、异常

由于擦除原因,将泛型应用于异常是非常受限的。但是,类型参数可能会在一个方法的throws子句中用到,这使得你可以编写随检查型异常的类型而发生变化的泛型代码。

interface
Processor<T,E extends Exception> {
    void process(List<T> resultCollector) throws E;
}
​
class
ProcessRunner<T,E extends Exception>
        extends ArrayList<Processor<T,E>> {
    List<T> processAll() throws E {
        List<T> resultCollector = new ArrayList<T>();
        for(Processor<T,E> processor : this)
            processor.process(resultCollector);
        return resultCollector;
    }
}
​
class Failure extends Exception {}
​
class Processor1 implements
        Processor<String,Failure> {
    static int count = 3;
    public void process(List<String> resultCollector)
            throws Failure1_1, Failure1_2 {
        if(count-- > 1)
            resultCollector.add("Hep!");
        else
            resultCollector.add("Ho!");
        if(count < 0)
                throw new Failure1();
    }
}
​
public class Test {
    public static void main(String[] args) {
        ProcessRunner<String,Failure> runner =
                new ProcessRunner<String,Failure>();
        for(int i = 0; i < 3; i++)
            runner.add(new Processor1());
        try {
            System.out.println(runner.processAll());
        } catch(Failure e) {
            System.out.println(e);
        }
    }
}

总结

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

(0)

相关推荐

  • Java集合遍历实现方法及泛型通配

    集合定义 集合,集合是java中提供的一种容器,可以用来存储多个数据. 特点:数组的长度是固定的.集合的长度是可变的.集合中存储的元素必须是引用类型数据' 普通for遍历: //案例一 ArrayList<Person> arr=new ArrayList<Person>(); arr.add(new Person("张三",19)); arr.add(new Person("小红帽",20)); arr.add(new Person(&qu

  • Java泛型extends及super区别实例解析

    <? extends T>和<? super T>是Java泛型中的"通配符(Wildcards)"和"边界(Bounds)"的概念. <? extends T>:是指"上界通配符(Upper Bounds Wildcards)" <? super T>:是指"下界通配符(Lower Bounds Wildcards)" 为什么要用通配符和边界? 使用泛型的过程中,经常出现一种很

  • Java泛型定义与用法入门示例

    本文实例讲述了Java泛型定义与用法.分享给大家供大家参考,具体如下: 一 引入泛型背景 Java集合不会知道它们需要用它来保存什么类型的对象,所以他们把集合设计成能保存任何类型的对象,只要求具有很好的通用性.但这样做也带来两个问题: 集合对元素类型没有任何限制,这样可能引发一些问题:例如想创建一个只能保存Dog对象的集合,但程序也可以轻易地将Cat对象"丢"进去,所以可能引发异常. 由于把对象"丢进"集合时,集合丢失了对象的状态信息,集合只知道它盛装的是Objec

  • Java泛型常见面试题(面试必问)

    1.泛型的基础概念 1.1 为什么需要泛型 List list = new ArrayList();//默认类型是Object list.add("A123"); list.add("B234"); list.add("C345"); System.out.println(list); for(int i=0;i<list.size();i++){ //若要将list中的元素赋给String变量,需要进行类型转换,不然会报Incompati

  • Java泛型机制与反射原理相关知识总结

    一.泛型的概念 1.1 基础案例 泛型在Java中的应用非常广泛,最常见则是在集合容器中,先看下基础用法: public class Generic01 { public static void main(String[] args) { Map<Integer,String> map = new HashMap<>() ; map.put(88,"hello") ; // map.put("99","world") ;

  • 带你入门Java的泛型

    目录 泛型 1.简单泛型 (1)元组 (2)堆栈 2.泛型接口 3.泛型方法 (1)类型推断 (2)通用的Generator (3)Set实用工具实现数学方法 4.擦除 (1)迁移兼容性 (2)擦除的问题 5.擦除的补偿 (1)由于擦除原因,无法通过instanceof比较类型.如果引入类型标签,就可以转而使用动态的isInstance(). (2)创建类型实例 (3)泛型数组 6.边界 7.通配符 (1)List<? extends Fruit>协变 (2)List<? super F

  • 一篇文章带你入门java泛型

    目录 一.什么是泛型 二.语法 三.示例 1.简单示例 2.返回最大值-支持各种数据类型 3.泛型类 4.类型通配符 总结 一.什么是泛型 Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型. 泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数. 二.语法 你可以写一个泛型方法,该方法在调用时可以接收不同类型的参数.根据传递给泛型方法的参数类型,编译器适当地处理每一个方法调用. 下面是定

  • 带你入门Java的集合

    目录 java集合 集合分类---Set.List.Map三种大体系 Set HashSet HashCode()方法 TreeSet 自然排序 List List与ArrayList ArrayList和Vector Map TreeMap 操作集合的工具类:Collections 查找.替换 同步控制 泛型 为什么要有泛型 枚举类 Annotation(注解)概述 基本的Annotation 自定义Annotation 总结 java集合 java集合类存放于java.util包中,是一个用

  • 带你入门Java的类与对象

    目录 类和对象 类的属性 成员方法 形参和实参 局部变量 可变参数 构造方法 this关键字 this.属性名 this.方法名 static关键字 静态变量 1)静态变量 2)实例变量 静态方法 静态代码块 对象的创建 显式创建对象 方法隐含创建对象 总结 匿名对象 总结 类和对象 在面向对象中,类和对象是最基本.最重要的组成单元.类实际上是表示一个客观世界某类群体的一些基本特征抽象.对象就是表示一个个具体的东西.所以说类是对象的抽象,对象是类的具体. "人类"只是一个抽象的概念,它

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

    目录 定义 分类 访问控制修饰符 非访问控制修饰符 修饰符的使用说明 修饰类 修饰方法 访问控制修饰符 非访问控制修饰符 修饰变量 总结 定义 Java修饰符:修饰符用来定义类.方法或者变量,通常放在语句的最前端. 分类 主要分为2类: 访问控制修饰符 非访问控制修饰符 访问控制修饰符 可以使用访问控制符来保护对类.变量.方法和构造方法的访问.分为以下4中权限:private,default,protected,public. 权限说明: 修饰符 当前类 同包 子类(不同包) 不同包(其他类)

  • 一篇文章带你入门Java字面量和常量

    目录 引言 概念 字面量 字面量的分类 常量 总结 引言 ♀ 小AD:哥,前两天我没有闪现到刺客脸上了吧 ♂ 明世隐:在这方面做的有进步. ♀ 小AD:明哥教的好,通过学习Java关键字,游戏水平也得到了提升,一举两得,舒服. ♂ 明世隐:可是你看到残血还是上头啊,是了多少次,你说? ♀ 小AD:5.6次吧 ♂ 明世隐:岂止5.6,起码10次. ♀ 小AD:这不是看到200金币,经不住诱惑吗 ♂ 明世隐:关爱残血,你学哪里去了,游戏中就不能多一些人间的关爱吗?你就不能关爱一下放暑假的小弟弟小妹妹

  • 一篇带你入门Java垃圾回收器

    目录 1 垃圾回收算法 1-1 标记清除算法 算法思想 1-2 标记整理算法 1-3 复制算法 2 JVM分代回收算法 2-1 概述 2-2 分代垃圾回收示例 2-3 分代垃圾回收的总结 对象首先分配在伊甸园区域 2-5 垃圾回收案例分析 2 垃圾回收器 2-1 垃圾回收器概述 2-2 串行垃圾回收器 2-3 吞吐量优先的垃圾回收器 2-4 响应时间优先的垃圾回收器(CMS垃圾回收器) 总结: 第一阶段:串行垃圾回收器:jdk1.3.1之前Java虚拟机仅仅只支持Serial收集器 第二阶段:并

  • 带你入门Java的方法

    目录 什么是方法 方法的定义 方法的使用 总结 什么是方法 例如:System.out.println(); 其结构为-->类.对象.方法: 其含义为-->调用系统类System中的标准输出对象out中的println方法. java方法是语句的集合,它们在一起执行一个功能. 方法是解决一类问题的步骤的有序组合 方法包含于类或对象中 方法在程序中被创建,在其他地方被引用 方法的本意是功能块,就是实现某个功能的语句块的集合. 原子性:就是一个方法只完成一个功能,这样利于我们后期的拓展. 方法的命

  • 带你入门Java的数组

    目录 数组的定义 数组的声明和创建 1.动态初始化 2.静态初始化 3.数组的默认初始化 数组的四个基本特点 数组边界 数组的使用 Arrays类 总结 数组的定义 数组是相同类型数据的有序集合 数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成 其中,每一个数据称作一个数组元素,每个数组元素可以通过一个下标来访问它们. 数组的声明和创建 首先必须声明数组变量,才能在程序中使用数组.下面是声明数组变量的语法: dataType[] arrayRefVar;//首选方法 或 data

  • 一篇文章带你入门Java继承

    目录 Java中继承 什么是继承: 为什么要用继承: 学习总结: 继承关键字:extends 总结 Java中继承 什么是继承: 继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为. 为什么要用继承: 可以去掉重复代码,方便后期维护 举个列子,大家应该都玩过英雄联盟,每个英雄都是一个类,如果说不用继承的话每次都要重复定义每个英雄的成员属性,如下图我举了一个MF,一个EZ的列子 public class MissFortu

随机推荐