Java笔记--泛型总结与详解

泛型简介:

在泛型没有出来之前,编写存储对象的数据结构是很不方便的。如果要针对每类型的对象写一个数据结构,
    则当需要将其应用到其他对象上时,还需要重写这个数据结构。如果使用了Object类型,编写的数据结构虽然
    通用性很好,但是不能保证存入的对象的安全性。

--支持知识共享,转载请标注地址"http://www.cnblogs.com/XHJT/p/3958036.html  "——和佑博客园,谢谢~~--
代码实例1:


不用泛型实现栈结构
    1.用Object和自定义栈类实现的一个入栈和出栈的小case;
    2.理解栈:栈是算法世界中经常要用到的一种数据结构,它可以实现元素的先进后出。常用于实现字符串反转,
        ·        四则运算等。

package com.xhj.generics.unused;

/**
 * 自定义Stack类
 *
 * @author XIEHEJUN
 *
 */
public class UsedStack {
    private Object[] os = new Object[10];
    private int index = 0;

    /**
     * 将一个元素入栈
     *
     * @param o
     *            要添加的元素对象
     */
    public void push(Object o) {
        if (index != os.length) {
            os[index++] = o;
        }
    }

    /**
     * 元素出栈,删除一个元素对象
     *
     * @return 返回出栈的元素对象
     */
    public Object pop() {
        if (index != -1) {
            return os[--index];
        }
        return null;
    }

    public boolean isEmty() {
        if (index == 0) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 输出栈中所有元素
     */
    public String toString() {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < os.length; i++) {
            if (os[i] != null)
                sb.append(os[i]);
        }

        return sb.toString();
    }

    public static void main(String[] args) {
        UsedStack us = new UsedStack();
        System.out.println("===================元素入栈====================");
        System.out.println("向栈添加三个元素");
        String[] strs = { "您好!", "我叫和佑!", "我喜欢Java!" };
        us.push(strs[0]);
        System.out.println("添加元素后的栈为:" + us);
        us.push(strs[1]);
        System.out.println("添加元素后的栈为:" + us);
        us.push(strs[2]);
        System.out.println("添加元素后的栈为:" + us);

        System.out.println("===================元素出栈====================");
        for (int i = 0; i < us.os.length; i++) {
            if (!us.isEmty()) {
                System.out.println("删除元素");
                System.out.println(us.pop());
            } else {
                System.out.println();
            }
        }
    }

}

注:从本实例可以看出:1.要想获取到适当的值,需要对类型进行强制转换,而本实例则通过重定义toString方法实现。
                            2.在本实例任何类型都可入栈,这意味着若是InputStream等类型入栈,在调用toString方法时将会抛出异常。

如:将上面的代码:us.push(strs[0]);

转换成:us.push(new InputStreamReader(System.in, "xhj"));

将会抛出:Exception in thread "main" java.io.UnsupportedEncodingException: xhj

at sun.nio.cs.StreamDecoder.forInputStreamReader(StreamDecoder.java:52)

at java.io.InputStreamReader.<init>(InputStreamReader.java:83)

at com.xhj.generics.unused.UsedStack.main(UsedStack.java:67)

使用泛型实现栈结构:

1.泛型是Java中的一个重要特性,使用泛型编程可以使代码获得最大的重要。

2.在使用泛型时要指明泛型的具体类型,这样可以避免类型转换。

3.泛型类是一个参数类型可变的类;固泛型参数只能是类类型。

代码实例:

package com.xhj.generics.used;

import java.util.LinkedList;

/**
 * 使用泛型实现栈的使用
 *
 * @author XIEHEJUN
 *
 * @param <T>
 */
public class UsedStack<T> {
    private LinkedList<T> list = new LinkedList<T>();

    /**
     * 入栈 向栈添加元素
     *
     * @param
     */
    public void push(T t) {
        list.addFirst(t);
    }

    /**
     * 出栈 删除元素
     *
     * @return
     */
    public T pop() {
        return list.removeFirst();
    }

    /**
     * 判断栈是否为空
     *
     * @return
     */
    public boolean isEmty() {
        if (list.size() == 0) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 重写toString方法
     */
    public String toString() {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i) != null)
                sb.append(list.get(i));
        }
        return sb.toString();
    }

    public static void main(String[] args) {
        UsedStack<String> us = new UsedStack<String>();
        System.out.println("===================元素入栈====================");
        System.out.println("向栈添加三个元素");

        String[] strs = { "您好!", "我叫和佑!", "我喜欢Java!" };
        us.push(strs[0]);
        System.out.println("添加元素后的栈为:" + us);
        us.push(strs[1]);
        System.out.println("添加元素后的栈为:" + us);
        us.push(strs[2]);
        System.out.println("添加元素后的栈为:" + us);

        System.out.println("===================元素出栈====================");
        for (int i = us.list.size() - 1; i >= 0; i--) {
            if (!us.isEmty()) {
                System.out.println("删除元素");
                System.out.println(us.pop());
                System.out.println("栈中元素还有个数为:" + i);
            } else {
                System.out.println("栈内已没有元素");
            }
        }

    }
}

注:泛型可以很好的解决上面出现的那两个问题,他的主要魅力就在于让程序有更好的可读性和安全性。

自定义泛型化数组类:

1.在Java虚拟机中并没有泛型类型的对象,所有有关泛型的信息都被擦除了。这虽然可以避免C++语言

的模版代码膨胀问题,但是也引起了其他问题。如:不能直接创建泛型数组等。

2.Java中的泛型不支持实例化类型变量。

3.通过Java的反射机制创建一个泛型化数组

newInstance(Class<?> componentType,int length)

代码实例:

package com.xhj.generics.used;

import java.lang.reflect.Array;

/**
 * 利用Java反射机制泛型化数组
 *
 * @author XIEHEJUN
 *
 * @param <T>数组类型
 */
public class GenericsArray<T> {
    private T[] array;
    private int size;

    /**
     * 泛型化数组构造函数
     *
     * @param type
     *            数组类型
     * @param size
     *            数组长度
     */
    @SuppressWarnings("unchecked")
    public GenericsArray(Class<T> type, int size) {
        array = (T[]) Array.newInstance(type, size);
        this.size = size;
    }

    /**
     * 向泛型化数组添加元素
     *
     * @param index
     * @param item
     */
    public void put(int index, T item) {
        if (index >= 0 && index < size) {
            array[index] = item;
        }
    }

    /**
     * 根据数组下标获取相应值
     *
     * @param index
     * @return
     */
    public T get(int index) {
        if (index >= 0 && index < size) {
            return array[index];
        }
        return null;
    }

    /**
     * 将泛型化数组打印输出
     *
     * @param t
     */
    public void printService(T[] t) {
        put(0, t[0]);
        System.out.println("添加的元素为:" + get(0));
        put(1, t[1]);
        System.out.println("添加的元素为:" + get(1));
        put(2, t[2]);
        System.out.println("添加的元素为:" + get(2));
    }

    public static void main(String[] args) {
        System.out.println("向泛型化数组添加String元素");
        GenericsArray<String> gStrArray = new GenericsArray<String>(
                String.class, 3);
        String[] strs = { "您好!", "我叫和佑!", "我喜欢Java!" };
        gStrArray.printService(strs);

        System.out.println("\n向泛型化数组添加Integer元素");
        GenericsArray<Integer> gIntArray = new GenericsArray<Integer>(
                Integer.class, 3);
        Integer[] arrays = { 10, 52, 32 };
        gIntArray.printService(arrays);
    }

}

总结:

Java泛型的局限性

1.不能使用基本类型作为其类型参数;

2.不能抛出或捕获泛型类型的实例、

3.不能直接使用泛型数组、

4.不能实例化类型变量

5.对于某些不足,可以通过Java的反射机制进行弥补。

泛型方法与数据查询

众所周知在使用JDBC查询数据库中数据的时候,返回的结果是ResultSet对象,这种机制,

我们在实际使用过程中是很不方便的。当然Java还提供了Commons DbUtils组件来将ResultSet

转化为Bean列表的方法,但是该在使用的时候是需要根据不同的Bean对象创建不同的查询方法的。

下面我将在此方法基础上使用泛型进行包装,以便提高它的通用性。

在Java中,不仅可以声明泛型类,还可以声明泛型方法:

1.使用<T>格式来表示泛型类型参数,参数个数可多个;

2.类型参数列表要放在访问权限修饰符、static和final之后;

3.类型参数列表要放在返回值类型、方法名称、方法参数之前。

代码实例:

对象实体类

package com.xhj.generics.used.entity;

/**
 * 用户实体类
 *
 * @author XIEHEJUN
 *
 */
public class User {
    private String userName;
    private String userId;
    private int userAge;
    private String userAddress;
    private String gende;
    private long userTell;

    public User() {
        super();
    }

    public User(String userName, String userId, int userAge,
            String userAddress, String gende, long userTell) {
        this.userName = userName;
        this.userId = userId;
        this.userAge = userAge;
        this.userAddress = userAddress;
        this.gende = gende;
        this.userTell = userTell;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getUserId() {
        return userId;
    }

    public int getUserAge() {
        return userAge;
    }

    public void setUserAge(int userAge) {
        this.userAge = userAge;
    }

    public String getUserAddress() {
        return userAddress;
    }

    public void setUserAddress(String userAddress) {
        this.userAddress = userAddress;
    }

    public String getGende() {
        return gende;
    }

    public void setGende(String gende) {
        this.gende = gende;
    }

    public long getUserTell() {
        return userTell;
    }

    public void setUserTell(long userTell) {
        this.userTell = userTell;
    }

    @Override
    public String toString() {
        return "User{" + "\n\tuserId =" +userId+ "\n\tuserName =" + userName
                + "\n\tuserAge =" + userAge + "\n\tgende =" + gende
                + "\n\tuserAddress =" + userAddress + "\n\tuserTell =" + userTell
                + "\n\t}";
    }
}

泛型数据访问操作类

package com.xhj.generics.used.dao;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.List;

import org.apache.commons.dbutils.DbUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;

/**
 * 数据库操作类,定义增删改查等操作方法
 *
 * @author XIEHEJUN
 *
 */
public class GenericQuery {
    private static String URL = "jdbc:oracle:thin:@192.168.100.13:1521:SIGMA";
    private static String DRIVRR = "ojdbc6";
    private static String USER = "PCD_Online_V2";
    private static String PASSWORD = "password";
    private static Connection con;

    /**
     * 获取数据库连接
     *
     * @return
     */
    public static Connection getConnecton() {
        DbUtils.loadDriver(DRIVRR);
        try {
            con = DriverManager.getConnection(URL, USER, PASSWORD);
        } catch (SQLException e) {
            System.out.println("连接失败");
        }
        return con;
    }

    /**
     * 查询数据
     *
     * @param sql
     *            SQL语句
     * @param type
     *            实体类类型
     * @return
     */
    @SuppressWarnings("unchecked")
    public static <T> List<T> query(String sql, Class<T> type) {
        QueryRunner qr = new QueryRunner();
        List<T> list = null;
        try {
            list = (List<T>) qr.query(getConnecton(), sql, new BeanListHandler(
                    type));
        } catch (SQLException e) {
            System.out.println("SQL语句不正确");
            e.printStackTrace();
        }finally{
            DbUtils.closeQuietly(con);
        }
        return list;
    }

    /**
     * 更新数据--增/删/改
     */
    public static void queryUpdate(String sql) {
        QueryRunner qr = new QueryRunner();
        try {
            qr.update(getConnecton(), sql);
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            DbUtils.closeQuietly(con);
        }
    }
}

业务操作类

package com.xhj.generics.used.service;

import java.util.List;
import com.xhj.generics.used.dao.GenericQuery;
import com.xhj.generics.used.entity.User;

/**
 * 调用数据库操作方法,对数据进行增删改查等操作
 *
 * @author XIEHEJUN
 *
 */
public class Service {
    /**
     * 插入数据
     *
     * @param user
     */
    public static void update(User user) {
        String sql = "insert into XHJUSER values(‘" + user.getUserId() + "‘,‘"
                + user.getUserName() + "‘,‘" + user.getUserAge() + "‘,‘"
                + user.getGende() + "‘,‘" + user.getUserAddress() + "‘,‘"
                + user.getUserTell() + "‘)";
        GenericQuery.queryUpdate(sql);
    }

    /**
     * 修改数据
     *
     * @param sql
     */
    public static void update(String sql) {
        GenericQuery.queryUpdate(sql);
    }

    /**
     * 查询数据
     *
     * @param user
     * @param sql
     */
    public static void select(User user, String sql) {
        List<User> list = GenericQuery.query(sql, User.class);
        System.out.println("表中数据有:");
        for (int i = 0; i < list.size(); i++) {
            System.out.println(i + "号对象属性值为:" + list.get(i));
        }
    }

    /**
     * 删除数据
     *
     * @param user
     */
    public static void delete(String sql) {
        GenericQuery.queryUpdate(sql);
    }
}

测试类:

package com.xhj.generics.used.main;

import com.xhj.generics.used.entity.User;
import com.xhj.generics.used.service.Service;

/**
 * 测试类
 *
 * @author XIEHEJUN
 *
 */
public class Test {

    public static void main(String[] args) {
        User user = new User("B", java.util.UUID.randomUUID().toString(), 12,
                "湖南", "女", 1213344455);
        Service.update(user);

        String sql = "select * from XHJUser where username = ‘B‘";
        Service.select(user, sql);

        sql = "update XHJuser set username = ‘D‘ where userid =‘1ab3ee1b-1c52-43d2-8df5-ffefb92c9c5c‘";
        Service.update(sql);

        sql = "delete from XHJuser where username = ‘C‘";
        Service.delete(sql);
    }

}

注:泛型类与泛型方法的重要区别

1.在使用泛型类时,需要注意不能将泛型参数类型用于静态域和静态方法中,而对于泛型方法则可以是静态的。

2.这种区别主要是"擦除"产生的。由于在泛型方法中已经指明了参数的具体类型,故即使发生擦除,也不会丢失。

泛型化方法与最小值

1.在Java中除了数值可以比较大小外,任何实现了Comparable接口的类的实例,都可以比较大小。

2.在比较类的对象是,需要限制比较的对象实现Comparable接口即:<T extends Comparable>

3.当泛型参数类型被限制为接口的子类型时,也使用extends关键字。

代码实例:

package com.xhj.generics.used;

/**
 * 利用泛型比较类对象实例大小
 *
 * @author XIEHEJUN
 *
 */
public class GenericComparable {
    /**
     * 比较并获取最小类对象实例
     *
     * @param array
     * @return
     */
    public static <T extends Comparable<T>> T getMin(T[] array) {
        if (array.length == 0 || array == null) {
            return null;
        } else {
            T min = array[0];
            for (int i = 0; i < array.length; i++) {
                if (min.compareTo(array[i]) > 0) {
                    min = array[i];
                }
            }
            return min;
        }
    }

    public static void main(String[] args) {
        String[] strs = { "您好!我是和佑b,来自和佑博客园", "您好!我是和佑a,来自和佑博客园",
                "您好!我是和佑c,来自和佑博客园" };
        System.out.println("最小的类对象实例为:" + getMin(strs));
    }

}

注:1.compareTo()方法先是逐步比较ASCII码,若是此时仍无法得出结果,再比较其长度

2.泛型类型参数的限定一般有两种情况:

a.小于某一个"范围"

b.大于某一个"范围"

范围即可以是一个类,也可以是一个接口,还可以是类和接口的组合,对于组合来说,需要将类放在第一位,并且用&分隔。

泛型化接口与最大值  
    1.在Java中除了可以定义类和方法,还可以定义泛型接口。泛型接口的作用和普通接口一样,只是它的实用性更强。

对于很多具体类型通用的方法,可以将其提取到一个泛型接口中,再编写一个泛型类实现这个接口即可。

2.定义泛型接口和定义泛型类是相似的,直接在接口名称后面加上<T>即可。T就是泛型类型参数,可以是多个。

3.在实现此接口时要注意,实现类的泛型参数和接口的泛型参数要相匹配。

代码实例:

泛型接口

package com.xhj.generics.used.ginterface;

/**
 * 定义一个泛型接口
 *
 * @author XIEHEJUN
 *
 */
public interface GenericComparableInterface {
    public <T extends Comparable<T>> T getMax(T[] array);
}
实现泛型接口
package com.xhj.generics.used.ginterface;

public class GenericComparableImp implements GenericComparableInterface {

    @Override
    public <T extends Comparable<T>> T getMax(T[] array) {
        if(array==null||array.length==0){
            return null;
        }else{
            T max = array[0];
            for (int i = 0; i < array.length; i++) {
                if(max.compareTo(array[i])<0){
                    max = array[i];
                }
            }
            return max;
        }
    }

    public static void main(String[] args) {
        GenericComparableImp gci = new GenericComparableImp();
        String[] strs = { "您好!我是和佑b,来自和佑博客园", "您好!我是和佑a,来自和佑博客园",
                "您好!我是和佑c,来自和佑博客园" };
        System.out.println("最小的类对象实例为:" +gci.getMax(strs));
    }
}

注:泛型接口的应用
    一个大型网站的后台往往使用多个数据表,可以将一些公共的操作如数据的增删改以及保存等放在一个泛型的DAO接口中定义,

在针对使用的持久层技术,编写此DAO的实现类,这些对于每一个持久化的对象,直接继承这个实现类,再去实现特有方法即可。

使用通配符增强泛型

1.Java中的数组支持协变类型,即如果方法参数是数组T,而S是T的子类,则方法也可以使用参数S。对于泛型类则没有这个特性。

为了弥补这个不足,Java推出了通配符类型参数。

2.使用通配符"?"可以让泛型在实际应用当中更加的灵活

3.通配符可以利用"extends"关键字来设置取值上限,如:<? extends Number>,参数类型要求继承Number

4.通配符可以设置取值下限,如:<?super Number>,参数类型要求是Number的父类

5.通配符可有多个"界限",如:实现多个接口,在接口间用&分隔。

代码实例:

package com.xhj.generics.used;

import java.util.ArrayList;
import java.util.List;

/**
 * 通配符在泛型中作用
 *
 * @author XIEHEJUN
 *
 */
public class Wildcard {
    /**
     * 获取基于Number父类下的list的中间数
     *
     * @param list
     * @return
     */
    public static Object getMiddle(List<? extends Number> list) {
        return list.get(list.size() / 2);
    }

    /**
     * 获取任何继承Object的List下的中间值
     *
     * @param list
     * @return
     */
    public static Object getMiddles(List<? extends Object> list) {
        return list.get(list.size() / 2);
    }

    public static void main(String[] args) {
        List<Integer> list = new ArrayList<Integer>();
        list.add(182);
        list.add(0115);
        list.add(8);
        list.add(502);
        list.add(233);
        System.out.println(getMiddle(list).toString());

        List<String> liststr = new ArrayList<String>();
        liststr.add("您好!");
        liststr.add("吃饭了吗!");
        liststr.add("美女!");
        liststr.add("下午有空吗!");
        liststr.add("看电影去吧!");
        System.out.println(getMiddles(liststr).toString());
    }

}

泛型化的折半查找法

1.查找就是在一组给定的数据集合中找出满足条件的数据。

2.折半查找要求数据集合中的元素必须可比较,且各元素按升序或者降序排列:

取集合的中间元素作为比较对象,则:

a.如果给定的值与比较对象相等,则查找成功,并返回中间元素的序号。

b.若大于比较对象,则在中间元素的右半段进行查找

c.若小于比较对象,则在中间元素的左半段进行查找

3.循环执行上述过程,直至查找成功,此时折半查找的平均时间复杂度是log2n

代码实例:

package com.xhj.generics.used;

/**
 * 泛型化折半查找算法
 *
 * @author XIEHEJUN
 *
 */
public class HalfSearch {

    /**
     * 折半查找的实现方法
     *
     * @param key
     * @param array
     * @return
     */
    public static <T extends Comparable<? super T>> int search(T key, T[] array) {
        int low = 0;
        int high = array.length - 1;
        int mid = 0;
        while (low <= high) {
            mid = (low + high) / 2;
            if (key.compareTo(array[mid]) == 0) {
                return mid;
            } else if (key.compareTo(array[mid]) > 0) {
                low += 1;
            } else {
                high -= 1;
            }
        }
        return -1;
    }

    public static void main(String[] args) {
        Integer[] array = { 12, 3, 8, 45, 26, 68 };
        String str = "GFISUDGHUIW";
        String[] arraystr = { str, "GYFSGHFUIH", "CD" };
        System.out.println("在String数组中‘GFISUDGHUIW‘的索引为:"
                + search(str, arraystr));
        System.out.println("在整型数组中‘3‘的索引为:" + search(3, array));
    }

}
时间: 2024-11-06 07:19:12

Java笔记--泛型总结与详解的相关文章

java笔记--枚举总结与详解

由于工作原因,已经有两礼拜没有更新博客了,好不容易完成了工作项目,终于又可以在博客园上愉快的玩耍了. 嗯,今天下午梳理了一下关于java枚举的笔记,比较长,不过还是觉得挺厚实的,哈哈,有出入的地方,欢迎朋友们指出来,一起学习,共同进步!! 一.枚举简介:     为什么要用枚举:     枚举是Java1.5出来之后新增的类型,它可以用来定义一组取值范围固定的的变量.     在枚举没有出来之前,要定义这样的变量,往往是通过定义一个接口,将不同的变量     使用不同的整数赋值.但是这样的却有着

java笔记之图形类详解

软件的交互方式:1. 控制台的交互方式.2. 图形化界面的交互方式 . java使用到的图形类主要在java.awt 与javax.swing包中. java.awt 与 javax.swing包的区别:java.awt中使用的图形类都是依赖于系统 的图形库的.javax.swing包使用到的图形类都是sun自己实现,不需要依赖系统的图形库.疑问: 既然swing包中的图形类已经取代awt包的图形类,为什么不删除awt呢? 1.swing比awt包出现的晚,所以会存在一些界面是用了awt包的相关

java笔记之图形类详解---事件监听器

事件监听器代表负责处理事件的接口.Java 提供了各种事件监听器类,但我们将讨论更频繁使用的那些事件监听器类.一个事件监听器的每个方法有一个参数作为一个对象,该对象是 EventObject 类的子类.例如,鼠标事件监听器的方法将接受 MouseEvent 的实例,其中 MouseEvent 是 EventObject 派生的. EventListner 接口 它是一个标记接口,每一个监听器接口必须扩展它.这个类定义在 java.util 包中. 事件: 当发生了某个事件的时候,就会有相应处理方

JAVA笔记-Static与Final详解笔记

static 成员变量 静态变量属于类的变量,所有类的实例共享的同一个变量. 直接使用类名读写这个变量 应用场景: 案例: public class Demo04 { public static void main(String[] args) { //静态变量属于类的 变量 //直接使用类名读写这个变量 Hoo.z = 10; int n = Hoo.z; System.out.println(n);//10 //实例变量x,y是属于对象的变量 //创建对象以后才能使用实例变量 //每个对象都

java中的io系统详解

java中的io系统详解 分类: JAVA开发应用 笔记(读书.心得)2009-03-04 11:26 46118人阅读 评论(37) 收藏 举报 javaiostreamconstructorstringbyte 相关读书笔记.心得文章列表 Java 流在处理上分为字符流和字节流.字符流处理的单元为 2 个字节的 Unicode 字符,分别操作字符.字符数组或字符串,而字节流处理单元为 1 个字节,操作字节和字节数组. Java 内用 Unicode 编码存储字符,字符流处理类负责将外部的其他

hadoop 学习笔记:mapreduce框架详解

hadoop 学习笔记:mapreduce框架详解 开始聊mapreduce,mapreduce是hadoop的计算框架,我 学hadoop是从hive开始入手,再到hdfs,当我学习hdfs时候,就感觉到hdfs和mapreduce关系的紧密.这个可能是我做技术研究的 思路有关,我开始学习某一套技术总是想着这套技术到底能干什么,只有当我真正理解了这套技术解决了什么问题时候,我后续的学习就能逐步的加快,而学习 hdfs时候我就发现,要理解hadoop框架的意义,hdfs和mapreduce是密不

Java网络编程和NIO详解9:基于NIO的网络编程框架Netty

Java网络编程和NIO详解9:基于NIO的网络编程框架Netty 转自https://sylvanassun.github.io/2017/11/30/2017-11-30-netty_introduction/ netty是基于NIO实现的异步事件驱动的网络编程框架,学完NIO以后,应该看看netty的实现,netty框架涉及的内容特别多,这里只介绍netty的基本使用和实现原理,更多扩展的内容将在以后推出. 本系列文章首发于我的个人博客:https://h2pl.github.io/ 欢迎

Java中的main()方法详解

在Java中,main()方法是Java应用程序的入口方法,也就是说,程序在运行的时候,第一个执行的方法就是main()方法,这个方法和其他的方法有很大的不同,比如方法的名字必须是main,方法必须是public static void 类型的,方法必须接收一个字符串数组的参数等等. 在看Java中的main()方法之前,先看一个最简单的Java应用程序HelloWorld,我将通过这个例子说明Java类中main()方法的奥秘,程序的代码如下: 1 /** 2 * Java中的main()方法

Java下static关键字用法详解

Java下static关键字用法详解 本文章介绍了java下static关键字的用法,大部分内容摘自原作者,在此学习并分享给大家. Static关键字可以修饰什么? 从以下测试可以看出, static 可以修饰: 1. 语句块 2. 成员变量(但是不能修饰局部变量) 3. 方法 4. 接口(内部接口) 5. 类(只能修饰在类中的类, 即静态内部类) 6. jdk 1.5 中新增的静态导入 那么static 修饰的表示什么呢? 当创建一个类时,就是在创建一个新类型,描述这个类的对象的外观和行为,除