출처: https://bumcrush.tistory.com/182 [맑음때때로 여름]

 

package dept;

public class Dept {
	
	// VO : 데이터를 저장하는 기능만 가지는 클래스, read Only
	// DTO : 데이터틀 저장하는 기능을 가지는 클래스, Write 가능
	
	public Dept(int deptno, String dname, String loc) {
		super();
		this.deptno = deptno;
		this.dname = dname;
		this.loc = loc;
	}
	
	private int deptno;
	private String dname;
	private String loc;
	
	
	
	
	@Override
	public String toString() {
		return "Dept [deptno=" + deptno + ", dname=" + dname + ", loc=" + loc + "]";
	}

	public int getDeptno() {
		return deptno;
	}
	public void setDeptno(int deptno) {
		this.deptno = deptno;
	}
	public String getDname() {
		return dname;
	}
	public void setDname(String dname) {
		this.dname = dname;
	}
	public String getLoc() {
		return loc;
	}
	public void setLoc(String loc) {
		this.loc = loc;
	}
	
}

 

package dept;

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

public class ConnectionProvider {

	public static Connection getConnection() throws SQLException {
		
		Connection conn = null;

         // 2. DB 연결 localhost == 127.0.0.1
         String jdbcUrl = "jdbc:mysql://localhost:3306/project?serverTimezone=UTC";
         String user = "hyo";
         String password = "admin";
         conn = DriverManager.getConnection(jdbcUrl, user, password);

         return conn;
	}
	
}

 

 

package dept;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

// DAO : Data Access Object -> 데이터베이스 처리하는 기능만 가지는 클래스
public class DeptDao {

	private static DeptDao dao = new DeptDao();
	
	private DeptDao() {
	}
	
	public static DeptDao getInstance() {
		return dao;
	}
	
	

	// 부서 입력
	int insertDept(Dept dept, Connection conn) {

		int resultCnt = 0;

		// DB 연결 : Connection
		try {
			// Statement
			// SQL : Insert into
			String sql = "insert into dept values(?,?,?)";
			PreparedStatement pstmt = conn.prepareStatement(sql);
			pstmt.setInt(1, dept.getDeptno());
			pstmt.setString(2, dept.getDname());
			pstmt.setString(3, dept.getLoc());

			// sql 실행
			resultCnt = pstmt.executeUpdate();

			pstmt.close();

		} catch (SQLException e) {
			e.printStackTrace();
		}

		// 결과
		return resultCnt;

	}

	// 부서 정보를 수정 : Dept
	int updateDept(Dept dept, Connection conn) {

		int resultCnt = 0;

		// DB 연결 : Connection
		try {
			// Statement
			// SQL : Update
			String sql = "update dept set dname=?, loc=? where deptno=? ";
			PreparedStatement pstmt = conn.prepareStatement(sql);
			pstmt.setInt(3, dept.getDeptno());
			pstmt.setString(1, dept.getDname());
			pstmt.setString(2, dept.getLoc());

			// sql 실행
			resultCnt = pstmt.executeUpdate();

			pstmt.close();

		} catch (SQLException e) {
			e.printStackTrace();
		}

		// 결과
		return resultCnt;

	}

	// 부서정보 삭제
	int deleteDept(int deptno, Connection conn) {

		int resultCnt = 0;

		// DB 연결 : Connection
		try {
			// Statement
			// SQL : delete
			String sql = "delete from dept where deptno=?";
			PreparedStatement pstmt = conn.prepareStatement(sql);
			pstmt.setInt(1, deptno);

			// sql 실행
			resultCnt = pstmt.executeUpdate();

			pstmt.close();

		} catch (SQLException e) {
			e.printStackTrace();
		}

		// 결과
		return resultCnt;
	}

	// 부서의 전체 리스트
	List<Dept> listDept(Connection conn) {

		List<Dept> list = new ArrayList<Dept>();

		Statement stmt = null;

		try {
			stmt = conn.createStatement();

			String sql = "select * from dept order by deptno";

			ResultSet rs = stmt.executeQuery(sql);

			while (rs.next()) {
				// Dept d = new Dept(rs.getInt(1), rs.getString(2), rs.getString(3));
				// list.add(d);
				list.add(new Dept(rs.getInt(1), rs.getString(2), rs.getString(3)));
			}

		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return list;
	}

	// 부서 하나 검색
	Dept searchDept(int deptno, Connection conn) {
		
		Dept dept = null;

		Statement stmt = null;

		try {
			stmt = conn.createStatement();

			String sql = "select * from dept where deptno="+deptno;

			ResultSet rs = stmt.executeQuery(sql);

			if(rs.next()) {
				dept = new Dept(rs.getInt(1), rs.getString(2), rs.getString(3));
			}

		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return dept;

	}

}

 

 

package dept;

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

public class DeptManager {

	// 사용자 입력
	Scanner sc = new Scanner(System.in);

	DeptDao dao = DeptDao.getInstance();

	// 부서입력 메소드 : 사용자에게 입력 받은 데이터를 DAO를 이용해서 DB 입력
	void insertDept() {

		// 부서정보를 받아서 인스턴스를 생성하고 dao.insertDept()

		System.out.println("부서정보를 입력합니다.");
		System.out.println("부서번호를 입력해주세요.");
		String deptno = sc.nextLine();
		System.out.println("부서이름을 입력해주세요.");
		String dname = sc.nextLine();
		System.out.println("지역 이름을 입력해주세요.");
		String loc = sc.nextLine();

		Dept dept = new Dept(Integer.parseInt(deptno), dname, loc);

		Connection conn = null;

		int resultCnt = 0;

		try {
			conn = ConnectionProvider.getConnection();
			
			resultCnt = dao.insertDept(dept, conn);
			
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		if(resultCnt>0) {
			System.out.println("입력되었습니다.");
		} else {
			System.out.println("입력이 실패했습니다.");
		}
	}


	// 부서 정보 수정 메소드 : 사용자에게 입력 받고 데이터를 DAO를 이용해서 수정
	void editDept() {
		
		System.out.println("수정을 원하시는 부서번호를 입력해주세요.");
		String deptno = sc.nextLine();
		System.out.println("새로운 부서 이름을 입력해주세요. ");
		String dname = sc.nextLine();
		System.out.println("새로운 지역 이름을 입력해주세요.");
		String loc = sc.nextLine();
		
		Dept dept = new Dept(Integer.parseInt(deptno), dname, loc);
		

		Connection conn = null;
		
		int resultCnt = 0;

		try {
			conn = ConnectionProvider.getConnection();
			
			resultCnt = dao.updateDept(dept, conn);
			
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		if(resultCnt>0) {
			System.out.println("수정되었습니다.");
		} else {
			System.out.println("수정이 실패했습니다.");
		}
		
		
	}

	
	// 부서 정보를 삭제
	void delDept() {
		
		System.out.println("삭제를 원하시는 부서번호를 입력해주세요.");
		String deptno = sc.nextLine();

		Connection conn = null;
		
		int resultCnt = 0;

		try {
			conn = ConnectionProvider.getConnection();
			
			resultCnt = dao.deleteDept(Integer.parseInt(deptno), conn);
			
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		if(resultCnt>0) {
			System.out.println("삭제되었습니다.");
		} else {
			System.out.println("지우려는 정보가 존재하지 않습니다.");
		}
		
		
	}
	
	void listDept() {
		
		Connection conn = null;
				
		List<Dept> list = null;

		try {
			conn = ConnectionProvider.getConnection();
			
			list = dao.listDept(conn);
			
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		if(list.isEmpty()) {
			System.out.println("저장된 정보가 없습니다.");
		} else {
			
			for(Dept d : list) {
				//System.out.println(d);
				System.out.printf("%5s", d.getDeptno()+"\t" );
				System.out.printf("%12s", d.getDname()+"\t" );
				System.out.printf("%12s", d.getLoc()+"\n" );
			}
			
			
		}
		
	}
	
	void searchDept() {
		
		System.out.println("부서를 검색합니다.");
		System.out.println("찾으시는 부서의 번호를 입력해주세요.");
		String deptno = sc.nextLine();
		

		Connection conn = null;

		Dept dept = null;

		try {
			conn = ConnectionProvider.getConnection();
			
			dept = dao.searchDept(Integer.parseInt(deptno), conn);
			
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		if(dept!=null) {
			System.out.println(dept);
		} else {
			System.out.println("찾으시는 정보가 존재하지 않습니다.");
		}
		
		
	}


}

 

 

package dept;

import java.util.Scanner;

public class DeptMain {

	public static void main(String[] args) {

		DeptManager manager = new DeptManager();

		Scanner sc = new Scanner(System.in);

		// 데이터 베이스 드라이버 로드
		try {
			Class.forName("com.mysql.cj.jdbc.Driver");

			while(true) {

				System.out.println("부서관리 메뉴를 입력해주세요.");
				System.out.println("1. 입력, 2. 수정, 3.삭제, 4. 전체리스트, 5. 검색, 6. 종료");
				System.out.println("__________________________________________________");

				String select = sc.nextLine();

				switch (select.charAt(0)) {
				case '1':
					manager.insertDept();
					break;
				case '2':
					manager.editDept();
					break;
				case '3':
					manager.delDept();
					break;
				case '4':
					manager.listDept();
					break;
				case '5':
					manager.searchDept();
					break;
				case '6':
					System.out.println("프로그램을 종료합니다.");
					return;
				}
			}
			

		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

}
package jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;

public class JDBCMysqlStatementTest {

	public static void main(String[] args) {
		Scanner sc= new Scanner(System.in);
		Connection conn = null;
		
		try {
			// 1. 드라이버 로드
	         Class.forName("com.mysql.cj.jdbc.Driver");
	         System.out.println("Driver Load!");
			
			// 2. DB 연결     localhost == 127.0.0.1
	         String jdbcUrl ="jdbc:mysql://localhost:3306/project?serverTimezone=UTC";
	         String user = "hyo";
	         String password = "admin";
	         
	         conn = DriverManager.getConnection(jdbcUrl, user, password);
	         System.out.println("데이터베이스에 접속했습니다!");
			
			// 3. statement 인스턴스생성
			
			Statement stmt = conn.createStatement();
			
			System.out.println("부서 이름을 입력해주세요.");
			String userDname= sc.nextLine();
			System.out.println("부서의 위치를 입력해주세요.");
			String userLoc = sc.nextLine();
			
			
			// 입력 : insert
			
			String sqlInsert = "insert into dept (deptno, dname, loc) values (80, '"+userDname+"','"+userLoc+"')";
				
			
			int resultCnt = stmt.executeUpdate(sqlInsert); // sql문을 실행하고 횟수반환
			if(resultCnt>0) {
				System.out.println("정상적인 입력");
			}
			
			// 4. sql 실행 : 부서리스트 출력
			String sql="select * from dept order by deptno";
			ResultSet rs = stmt.executeQuery(sql);
			
			// 5. ResultSet을 이용해서 결과 출력
			while(rs.next()) { 			// rs.next(); // boolean Type
	              int deptno = rs.getInt("deptno");
	              String dname = rs.getString("dname");
	              String loc = rs.getString(3);
	              
	              // System.out.println(deptno+"\t"+dname+"\t"+loc);
	              System.out.printf("%5s",deptno+"\t");
	              System.out.printf("%12s",dname+"\t");
	              System.out.printf("%12s",loc+"\n");

			}
			
			rs.close();
			stmt.close();
			conn.close();		
			
		} catch (ClassNotFoundException e) {
			System.out.println("Driver 로드 실패");
			
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		
		 
		
		
		
	}

}​
package jdbc;

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

public class JDBCMysqlConnectionTest {

   public static void main(String[] args) {

      Connection conn = null;
      
      try {
         // 1. 드라이버 로드
         Class.forName("com.mysql.cj.jdbc.Driver");
         System.out.println("Driver Load!");
         
         // 2. DB 연결       localhost == 127.0.0.1
         String jdbcUrl ="jdbc:mysql://localhost:3306/project?serverTimezone=UTC";
         String user = "hyo";
         String password = "admin";
         
         conn = DriverManager.getConnection(jdbcUrl, user, password);
         System.out.println("데이터베이스에 접속했습니다.");
         
         // ....
         
         
         conn.close();
         
   
      } catch (ClassNotFoundException e) {
         System.out.println("Driver 로드 실패");
         e.printStackTrace();
      } catch (SQLException e) {
         e.printStackTrace();
      }
      
      
      
      
      
   }

}
package jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Scanner;

public class JDBCMysqlPreparedTest {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		Connection conn = null;

		try {
			// 1. 드라이버 로드
			Class.forName("com.mysql.cj.jdbc.Driver");
			System.out.println("Driver Load!");

			// 2. DB 연결 localhost == 127.0.0.1
			String jdbcUrl = "jdbc:mysql://localhost:3306/project?serverTimezone=UTC";
			String user = "hyo";
			String password = "admin";

			conn = DriverManager.getConnection(jdbcUrl, user, password);
			System.out.println("데이터베이스에 접속했습니다.");

			// Statement stmt = conn.createStatement();

			System.out.println("부서 번호 입력해주세요.");
			int userDeptno = sc.nextInt();
			sc.nextLine();
			System.out.println("부서 이름을 입력해주세요.");
			String userDname = sc.nextLine();

			System.out.println("부서의 위치를 입력해주세요.");
			String userLoc = sc.nextLine();

			// PreparedStatement 인스턴스 생성
			String sqlInsert = "insert into dept values (?, ?, ?)";

			PreparedStatement pstmt = conn.prepareStatement(sqlInsert);
			pstmt.setInt(1, userDeptno);
			pstmt.setString(2, userDname);
			pstmt.setString(3, userLoc);

			int resultCnt = pstmt.executeUpdate();

			if (resultCnt > 0) {
				System.out.println("정상적으로 입력되었음.");
			} else {
				System.out.println("데이터 입력이 되지 않았음.");
			}

			// 부서 리스트 출력
			String sqlList = "select * from dept order by loc";
			pstmt = conn.prepareStatement(sqlList);
			ResultSet rs = pstmt.executeQuery();

			while (rs.next()) {
				System.out.print(rs.getInt(1) + ", ");
				System.out.print(rs.getString(2) + ", ");
				System.out.print(rs.getString(3) + "\n");
			}

			rs.close();
			pstmt.close();
			conn.close();

		} catch (ClassNotFoundException e) {
			System.out.println("Driver 로드 실패");

		} catch (SQLException e) {
			e.printStackTrace();
		}

	}

}

1) 커넥트 파일 위치 알아두기 

- 헛갈리지 않게 따로 복사해서 보관해두는 것도 좋다.

 

2) 라이브러리 불러오기  Build Path - Configure Build Path

 

3 Add Extenal Jars

 

 

4-1) Mysql

4-2) Oracle sql

 

STATEMENT

 

package jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;

public class JDBCOracleStatementTest {

	public static void main(String[] args) {
		Scanner sc= new Scanner(System.in);
		Connection conn = null;
		
		try {
			// 1. 드라이버 로드
			Class.forName("oracle.jdbc.driver.OracleDriver");
			System.out.println("Oracle Driver Load !!!");
			
			// 2. DB 연결     localhost == 127.0.0.1
			String jdbcUrl = "jdbc:oracle:thin:@localhost:1521:orcl";
			String user = "scott";
			String password = "tiger";
			
			conn = DriverManager.getConnection(jdbcUrl, user, password);
			System.out.println("데이터베이스에 접속했습니다.");
			
			// 3. statement 인스턴스생성
			
			Statement stmt = conn.createStatement();
			
			System.out.println("부서 이름을 입력해주세요.");
			String userDname= sc.nextLine();
			System.out.println("부서의 위치를 입력해주세요.");
			String userLoc = sc.nextLine();
			
			
			// 입력 : insert
			
			String sqlInsert = "insert into dept values (SEQ_DEPT_DEPTNO.NEXTVAL,'"+userDname+"','"+userLoc+"')";
				
			
			int resultCnt = stmt.executeUpdate(sqlInsert); // sql문을 실행하고 횟수반환
			if(resultCnt>0) {
				System.out.println("정상적인 입력");
			}
			
			// 4. sql 실행 : 부서리스트 출력
			String sql="select * from dept order by deptno";
			ResultSet rs = stmt.executeQuery(sql);
			
			// 5. ResultSet을 이용해서 결과 출력
			while(rs.next()) { 			// rs.next(); // boolean Type
				int deptno = rs.getInt("deptno");
				String dname = rs.getString("dname");
				String loc = rs.getString(3);
				System.out.println(deptno+", "+ dname+ ", "+loc);
				
			}
			
			rs.close();
			stmt.close();
			conn.close();		
			
		} catch (ClassNotFoundException e) {
			System.out.println("Driver 로드 실패");
			
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		
		 
		
		
		
	}

}

 

 

PREPAREDSTATEMENT

 

package jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Scanner;

public class JDBCOraclePreparedTest {

	public static void main(String[] args) {
		Scanner sc= new Scanner(System.in);
		Connection conn = null;
		
		try {
			// 1. 드라이버 로드
			Class.forName("oracle.jdbc.driver.OracleDriver");
			System.out.println("Oracle Driver Load !!!");
			
			// 2. DB 연결     localhost == 127.0.0.1
			String jdbcUrl = "jdbc:oracle:thin:@localhost:1521:orcl";
			String user = "scott";
			String password = "tiger";
			
			conn = DriverManager.getConnection(jdbcUrl, user, password);
			System.out.println("데이터베이스에 접속했습니다.");
			
		
			//Statement stmt = conn.createStatement();
			
			System.out.println("부서 이름을 입력해주세요.");
			String userDname= sc.nextLine();
			System.out.println("부서의 위치를 입력해주세요.");
			String userLoc = sc.nextLine();
			
			
			// PreparedStatement 인스턴스 생성
			String sqlInsert = "insert into dept values (Seq_dept_deptno.nextval, ?, ?)";
			
			PreparedStatement pstmt = conn.prepareStatement(sqlInsert);
			pstmt.setString(1, userDname);
			pstmt.setString(2, userLoc);
			
			int resultCnt = pstmt.executeUpdate();
			
			if(resultCnt>0) {
				System.out.println("정상적으로 입력되었음.");
			}else {
				System.out.println("데이터 입력이 되지 않았음.");
			}
			
			// 부서 리스트 출력
			String sqlList ="select * from dept order by loc";
			pstmt = conn.prepareStatement(sqlList);
			ResultSet rs = pstmt.executeQuery();
			
			while(rs.next()) {
				System.out.print(rs.getInt(1)+", ");
				System.out.print(rs.getString(2)+", ");
				System.out.print(rs.getString(3)+"\n");
			}
			
			rs.close();
			pstmt.close();
			conn.close();
			
		} catch (ClassNotFoundException e) {
			System.out.println("Driver 로드 실패");
			
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		
		 
		
		
		
	}

}

 

 

PREPAREDSTATEMENT 2) 검색

 

package jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;

public class JDBCOraclePreparedTest2 {

   public static void main(String[] args) {

      Scanner sc = new Scanner(System.in);
      
      Connection conn = null;
      
      try {
         // 1. 드라이버 로드
         Class.forName("oracle.jdbc.driver.OracleDriver");
         System.out.println("Oracle Driver Load!");
         
         // 2. DB 연결       localhost == 127.0.0.1
         String jdbcUrl ="jdbc:oracle:thin:@localhost:1521:orcl";
         String user = "scott";
         String password = "tiger";
         
         conn = DriverManager.getConnection(jdbcUrl, user, password);
         System.out.println("데이터베이스에 접속했습니다.");
         
         
         // 3. statement 인스턴스생성
         PreparedStatement pstmt = null;

         
         System.out.println("검색하고 싶은 부서 이름을 입력하세요.");
         String searchDname = sc.nextLine();
         
         // 부서 정보 리스트 
         String sqlSelect = "select * from dept where dname=? order by loc";
         
         pstmt = conn.prepareStatement(sqlSelect);
         pstmt.setString(1, searchDname);
         
         ResultSet rs = pstmt.executeQuery();
         
         if(!rs.next()) {
            System.out.println("검색 결과 X");
         } else {
            do  {
               System.out.print(rs.getInt(1)+"\t");
               System.out.print(rs.getNString(2)+"\t");
               System.out.print(rs.getNString(3)+"\n");
            } while(rs.next());
         }
         
         
         rs.close();
         pstmt.close();
         conn.close();
         
         
         
      } catch (ClassNotFoundException e) {
         System.out.println("Driver 로드 실패");
      } catch (SQLException e) {
         e.printStackTrace();
      }
      
      
      
      
      
   }

}

소켓(Socket)이란?

소켓은 TCP를 위한 구조이다. TCP를 사용하여 응용 프로그램끼리 통신을 하기 위해서는 먼저 연결을 하여야 하는데 연결을 하기 위해서느 연결 끝점(End point)가 있어야 한다. 이 연결끝점이 바로 Socket이다.

 

 

Socket 클래스

생성자 설명
Socket (String host, int port) 호스트 이름이 host이고 포트 번호가 port인 새로운 소켓을 생성한다
Socket (InetAddress address, int port) InetAddress에 기술된 주소로 새로운 소켓을 생성한다
메소드 설명
InputStream getInputStream() 소켓이 사용하는 입력 스트림을 반환한다
OutputStream getOutputStream() 소켓이 사용하는 출력 스트림을 반환한다
Inetaddress getInetAddress() 소켓이 연결되어 있는 인터넷 주소를 반환한다
public int getLocalPort() 소켓이 연결되어 있는 포트 번호를 반환한다
public int getPort() 원격 컴퓨터의 포트번호를 반환한다
pbulic InetAddress getLocalAddress() 소케싱 연결되어 있는 인터넷 주소를 반환한다

 

ServerSocket 클래스

생성자 설명
public ServerSocket(int port) throws IOException 포트번호 Port에 대해 ServerSocket의 새로운 인스턴스를 만든다.
포트번호 0은 비어있는 포트번호를 사용한다는 의미이다.
queue는 서버가 받을 수 있는 입력 연결의 개수를 의미한다.
(디폴트는 50연결이다)
address는 컴퓨터의 인터넷 주소를 나타낸다.
public ServerSocket(int port, int queue) throws IOException
public ServerSocket(int port, int queue, InetAddress address ) throws IOException
메소드 설명
public socket accept() 접속요청을 받는다
public void close() ServerSocket을 닫는다
public Inetaddress getInetAddress() 소켓이 연결되어 있는 인터넷 주소를 반환한다
public int getSoTimeout() 소켓에 대한 타임아웃값을 밀리 초로 반환하거나 설정한다.

 

 

소켓클래스를 이용한 채팅방

 

서버)

package network;

import java.io.DataInput;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;

public class TCPIPChatMultichatServer {

	// 접속 사용자 정보를 저장 : 메세지를 전체에게 보내기 위해서
	// 저장정보 : name, OutputStream
	// Map<String, Object>로 저장
	HashMap<String, Object> clients;

	public TCPIPChatMultichatServer() {
		clients = new HashMap<String, Object>();
		Collections.synchronizedMap(clients); // 스레드 동기화에 안전한 상태로 해주는메서드
	}

	public void start() throws IOException {

		// Server Socket 생성
		// 사용자의 요청이 있으면 Socket 생성해서 연결 > Clients 사용자 정보를 저장
		// 연결 > Clients 사용자 정보를 저장 스레드로 처리

		ServerSocket serverSocket = new ServerSocket(7777);
		System.out.println("Chatting Server Start!");

		Socket socket = null;
		
		while(true) {
		// 요청이 들어올 때까지 대기 하다가 요청이 들어오면 새로운 소켓을 생성해서 반환
		socket = serverSocket.accept();
		// map에 정보저장, 접속한 사람들에게 메세지를 전송
		
		System.out.println("["+socket.getInetAddress()+socket.getPort()+"] 사용자 접속");
		
		ServerReceiver receiver = new ServerReceiver(socket);
		receiver.start();
			
		}

	}

	void SendToAll(String msg) {
		// 일괄처리 - Map은 순서가 없다 - Map이 가지고 있는 key를 Set으로 만든다.
		Set<String> keys = clients.keySet();
		Iterator<String> itr = keys.iterator();

		while (itr.hasNext()) {
			DataOutputStream out = (DataOutputStream) clients.get(itr.next()); // 키값가져오기
			try {
				out.writeUTF(msg);
			} catch (IOException e) {
				e.printStackTrace();
			}

		}

	}

	// 내부클래스 : 데이터 받아서 저장, 메시지 전체 발송
	private class ServerReceiver extends Thread {
		// Socket, InputStream, OutputStream
		Socket socket;
		DataOutputStream out;
		DataInputStream in;

		public ServerReceiver(Socket socket) {
			this.socket = socket;

			try {
				in = new DataInputStream(socket.getInputStream());
				out = new DataOutputStream(socket.getOutputStream());
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}
		@Override
		public void run() {
		 String name=null; // 접속한 사용자 이름
		 try {
			name= in.readUTF();		// 이름을 스트림을 통해 받는다
			clients.put(name, out); // map에 사용자 정보 저장
			SendToAll(">>>>>>>>>> " +name+"님이 접속하셨습니다.");// 내부클래스에서는 외부 클래스의 멤버를 참조할 수 있다.
			
			while(in !=null ) {
				SendToAll(in.readUTF());
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			clients.remove(name);
			System.out.println(name+"님이 나가셨습니다.");
			
		}
		}

	}

	public static void main(String[] args) throws IOException {
		new TCPIPChatMultichatServer().start();

	}
}

 

클라이언트)

package network;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;

import thread.threadMain;

public class TCPIPMulitiChatClient {

	public static void main(String[] args) {
	
		String serverIp = "192.168.0.32"; // localhost > 호스트자신의 주소
		
		//Socket연결
		try {
			Socket socket = new Socket(serverIp, 7777);
			
			// 메세지를 받는 스레드
			Thread receiver = new ClientReceiver(socket);
			
			// 메세지를 보내는 스레드
			Thread sender = new ClientSenderThread(socket, "포그바");
			
			sender.start();
			receiver.start();
			
		} catch (UnknownHostException e) {
	
			e.printStackTrace();
		} catch (IOException e) {	
			e.printStackTrace();
		}
		
	}

}

class ClientSenderThread extends Thread{
	
	
	// 보내기 스레드는 Socket, OutputStream, name도 필요하다.
	
	Socket socket;
	DataOutputStream out;
	String name;
	
	public ClientSenderThread(Socket s, String name) {
		this.socket = s;
		
		try {
			out = new DataOutputStream(s.getOutputStream());
			this.name = name;
			
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void run() {

		 Scanner sc = new Scanner(System.in);
		 
			try {
				// 접속하면 이름을 서버에 전송 
				if(out != null) {
				out.writeUTF(name);
				}
				
				while(out!=null) {
					out.writeUTF("["+name+"]"+sc.nextLine());
					
			}
			}catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	

class ClientReceiver extends Thread {
	// 메세지를 받아서 콘솔에 출력
	// Socket, InputStream, 필요
	
	Socket socket;
	DataInputStream in;
	
	public ClientReceiver(Socket socket) {
		this.socket = socket;
	
		try {
			in = new DataInputStream(socket.getInputStream());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	@Override
	public void run() {
		while (in != null){
			try {
				System.out.println(in.readUTF());
			} catch (IOException e) {

			}
		}
	}
	
	
}

URL (Uniform Resource Locator)

인터넷상의 파일이나 데이터베이스같은 자원에 대한 주소를 지정하는 방법이다.

 

URL클래스

자바에서는 URL 객체를 이용하여 URL의 주소를 나타낸다.

URL 객체를 생성하는 방법은 다음과 같다.

(URL이 잘못 지정되었을 경우에는 MalformedURLException 예외를 발생시킨다.)

 

URL java = new URL("http:javappo.tistory.com");

 

URL 클래스의 메소드

메소드 설명
getprotocol() URL 주소의 프로토콜을 반환한다
getAuthority() URL 주소의 권한 요소를 반환한다
getHost() URL 주소의 호스트 이름을 반환한다
getPort() URL 주소의 포트 번호를 반환한다
getPath() URL 주소의 경로 요소를 반환한다
getQuery() URL 주소의 쿼리 요소를 반환한다
getFile() URL 주소의 파일 이름을 반환한다
getRef() URL 주소의 참조 요소를 반환한다

 

URLConnection 클래스

URL 객체를 생성한 후에 URL 클래스의 OpenConnection() 메소드를 호출하면 URLConnection 객체를 반환한다.

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

public class memojang {

	public static void main(String[] args) {
		
		try {
			URL java = new URL("https://javappo.tistory.com/");
			URLConnection uc=java.openConnection();
			//url에 대한 새로운 URLConnection 객체/인스턴스를 생성한다.			
		} catch (MalformedURLException e) { // new URL() 실패
			e.printStackTrace();
		} catch (IOException e) {    // openConnection() 실패
			e.printStackTrace();
		}

}

}
멤버변수 설명
Protected URL url 이 연결이 통신하는 대상인 파일이나 객체를 가지고 있다
Protected boolean allowUserInteraction true로 설정되면 패스워드 대화상자같은 사용자와 상호작용을 허용한다.
Protected boolen connected 현재 연결의 상태를 가지고 있다.
Protected boolean doInput true로 설정되면 이 URL이 입력을 위하여 사용됨을 의미한다.
Protected bollen doOutput true이 설정되면 이 URL이 출력을 위하여 사용됨을 의미한다.

생성자와 메소드

Protected URLconnection(URL url) url에 대한 새로운 URLConnection 객체를 생성한다
Protected abstract void connect() url에 대한 연결을 시도한다

 

 

URLConnection을 이용한 읽기

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

public class UTLconnectionTest {

	public static void main(String[] args) {

		
		try {
			// url 인스턴스 생성
			String urlpath = "http://www.ctware.net";
			URL url = new URL(urlpath);
			
			// urlconnection 인스턴스
			URLConnection conn = url.openConnection();
			
			// 연결된 파일(자원)을 읽을 스트림 생성
			BufferedReader in = null;
			
			// URLConnection 인스턴스에서 InputStream을 얻을 수 있다.
			InputStream is = conn.getInputStream(); 
			
			Reader reader = new InputStreamReader(is);
			
			in = new BufferedReader(reader);
			
			// 한줄씩 읽어올 임시 변수
			String str=null;
			
			while(true) {
				str=in.readLine();
				System.out.println(str);
				if(str==null) {
					break;
				}
			}
			
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {

			e.printStackTrace();
		}

	}

}
<출력>

<html>
<head>
</head>
<body>
<center>
<h1>DOTHOME WEB SERVER : <?php echo $_SERVER["HTTP_HOST"]?></h1>
<hr/>
<p>Copyright 2016~ DOTHOME.CO.KR</p>
</center>
</body>
</html>
null

쓰레드


– 자바에서 스레드를 사용하는 이유는 비동기적 작동 방식(독립스레드)에 대한 개념이 없음
 • 프로그래밍 방식이 자바에서는 사용이 가능하지 않음
 • 비동기적 작동 방식 구현 : ‘스레딩 기술의 사용 방법’ 숙지
– 자바가 실행되는 기반인 자바가상머신(Java virtual machine, 이하 JVM) 자체가 하나의 프로세스임
 • 언어적 차원 : 스레드의 동기화 지원 가능
 • 다중 스레드 프로그램을 쉽고 명료하게 만들 수 있음

 

다중 쓰레드

– 시분할 기법(Time-Shared)
• 멀티태스킹 및 멀티스레드를 가능하게 하는 기법
• 아주 짧은 시간 간격을 두고 여러 개의 프로그램을 전환하면서 실행
• 빠른 속도 때문에 두 개 이상의 프로그램이 동시에 실행되는 것처럼 느껴짐
• 프로그램의 실행을 전환하는 것은 OS가 담당함


– 다중 스레드의 이점
• 자원을 효율적으로 사용할 수 있음
• 사용자에 대한 응답성이 향상됨
• 작업이 분리되어 코드가 간결함


– 다중 스레드의 단점
• 동기화에 주의해야 함
• 교착상태가 발생하지 않도록 주의해야 함
• 각 스레드가 효율적으로 고르게 실행될 수 있게 해야 함

 

–다중 스레드의 사용 예

• 스마트폰 게임
 – 메인스레드 : 게임을 하기 위한 UI부분을 그려줌
 – 그래픽 부분 담당 코드 : 순차적으로 실행, UI를 그리는 서버통신을 담당하는 소켓부분을 방치하는 수 밖에 없음.
 – 통신을 담당하는 스레드를 따로 하나를 두어 일정한 시간단위로 체크할 수 있도록 해야 함.


• 영상통신

– 영상을 받아 화면에 출력해 주는 코드와 영상을 생성하여 보내주는 코드를 만드는 경우 

   > 적어도 2개의 작업이 동시에 일어난다는 것을 알 수 있음
– 두 가지 이상의 일을 구현하기 위해 다중 스레드를 사용함

 

 


< 스레드 사용 방법 >

예제 extends Thread

package thread;

// 쓰레드 클래스의 정의는 thread클래스를 상속해서 정의
public class showThread extends Thread {

	String threadName;
	
	public showThread(String name) {
		this.threadName=name;
	}
	
	@Override
	public void run() {
		
		for(int i=0; i<100; i++) {
			System.out.println("안녕하세요" + threadName + "입니다.");
			try {
				// object클래스의 sleep() 메서드 : 현재 스레드를 1/1000초 간격으로 멈춤
				sleep(100);// 100/1000초 > 1/10초 

			} catch (InterruptedException e) {
				e.printStackTrace();
			} 
			
		} System.out.println(threadName + " 종료 ★");
	}

}
package thread;

public class threadMain {

	public static void main(String[] args) {

		
		// Thread 생성
		
		showThread st1 =new showThread("1번 스레드");
		showThread st2 =new showThread("2번 스레드");
		
		st1.start();
		st2.start();
	
		
		for(int i=0; i<100; i++) {
			System.out.println("메인스레드");
		}
		
		System.out.println("★끝★");
	}

}

< 출력 >

main스레드에 Thread.sleep(100)을 똑같이 넣어주면 셋이 번갈아서 실행됨

 


예제 implements Runnable

package thread;

// 쓰레드 클래스 정의할 때 상속이 필요한 경우 Runnable 인터페이스를 구현해서 스레드를 생성할 수 있다.
public class ShowRunnable implements Runnable {

	
	public void run() {
		for(int i=0; i<100; i++) {
			System.out.println("러너블스레드");
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {

				e.printStackTrace();
			}
		}
		
		System.out.println("★끝★");
	}

}
package thread;

public class threadMain2 {

	public static void main(String[] args) {

				
		// Runnable 인터페이스를 이용한 스레드
		Runnable target = new ShowRunnable();
		Thread st3 = new Thread(target);
		
		st3.start();
		
	
		
		for(int i=0; i<100; i++) {
			System.out.println("메인스레드");
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {

				e.printStackTrace();
			}
		}
		
		System.out.println("★끝★");
	}

}

<출력 / 100개 반복>


스레드 우선순위 설정

		// 우선순위 설정 1-10 : 기본5
		st1.setPriority(Thread.MAX_PRIORITY);
		st2.setPriority(Thread.MIN_PRIORITY);

<출력> ~ 속도가 빨라서 별차이가 없지만 방법은 ARADUZA ~


t1.join(); // t1 스레드가 종료될때까지 다른 스레드는 멈춘상태

예제)

package thread;

public class Sum {
	
	int num;
	
	Sum(){
		num=0;
	}
	
	void addNum(int n) {
		num+=n;
	}
	
	int getNum() {
		return num;
	}

	public void run() {
		// TODO Auto-generated method stub
		
	}

}
package thread;

public class Adderthread extends Sum implements Runnable  {
	
	int start;
	int end;
	
	Adderthread(int n1, int n2){
		start=n1;
		end=n2;
	}

	@Override
	public void run() {
		for(int i=start; i<=end;i++) {
			addNum(i);
		}
	}
}
package thread;

public class AdderThreadMain {

	public static void main(String[] args) {
		
		Adderthread at1 = new Adderthread(1, 500000);
		Adderthread at2 = new Adderthread(500000, 1000000);
		
		// 쓰래드 생성
		Thread t1 = new Thread(at1);
		Thread t2 = new Thread(at2);
		
		t1.start();
		t2.start();
		
		try {
			t1.join(); // t1 쓰래드가 종료될 때 까지 다른 쓰래드는 멈춤상태
			t2.join();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		System.out.println("1~100 합은 : " + (at1.getNum()+at2.getNum()) );
		

	}

}

<출력>

1~100 합은 : 1784793664


멀티스레드 예제

package thread;

import javax.swing.JOptionPane;

public class ThreadTestMain1 {

	// 다른 스레드에서도 참조가 가능한 클래스 변수 
	public static boolean check = false; // 10초 지나면 꺼지게하려고 만듦 (안에서사용하려고)
	
	public static void main(String[] args) {

//		String age= JOptionPane.showInputDialog("나이를 입력해주세요");		
//		int ageNumber=Integer.parseInt(age);		
//		System.out.println("저의 나이는 " + age + "세 입니다.");		
//		for(int i=10; i>0; i--) {
//			System.out.println(i);
//			try {
//				Thread.sleep(1000);
//			} catch (InterruptedException e) {
//				e.printStackTrace();
//			}
//		}                       // 나이쓰는 창뜨고 > 숫자셈
		
		InputAgeThread iat= new InputAgeThread();
		CountDownThread cdt=new CountDownThread();
		
		iat.start();
		cdt.start();
	}

}

class InputAgeThread extends Thread{

	@Override
	public void run() {
		System.out.println("10초 안에 입력하세요.");
		String age= JOptionPane.showInputDialog("나이를 입력해주세요");
		System.out.println("저의 나이는 " + age + "세 입니다.");
		ThreadTestMain1.check=true;
		
	}
	

	

}

class CountDownThread extends Thread {

	@Override
	public void run() {
		for(int i=10; i>0; i--) {
			if(ThreadTestMain1.check) {
				break;                    // 입력되면 숫자세기 STOP
			}
			System.out.println(i);
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		System.exit(0);
	}
	
	
}

'


스레드 동기화

 

Note that this implementation is not synchronized
API 문서에는 해당 클래스의 인스턴스가 둘 이상의 쓰레드가 동시에 접근을 해도 문제가 발생하지 않는지를 명시하고 있다.  따라서 쓰레드 기반의 프로그래밍을 한다면, 특정 클래스의 사용에 앞서 쓰레드에 안전한지를 확인 해야 한다.

ex) String buffer / builder

 

쓰레드의 동기화 - synchronized
- 한 번에 하나의 쓰레드만 객체에 접근할 수 있도록 객체에 락(lock)을 걸어서 데이터의 일관성을 유지하는 것.

 

아래 예제)

Sum 클래스의 Void addNum에  synchronized가 없으면 동기화가 되지 않아서 매번 값이 다르다..

그러나 엄청난 성능의 감소를 동반한다.

package thread;

public class Sum {
	
	int num;
	
	Sum(){
		num=0;
	}
	
	// 동기화~!
	synchronized void addNum(int n) {
		num+=n;
	}
	
	int getNum() {
		return num;
	}

	public void run() {
		// TODO Auto-generated method stub
		
	}

}
package thread;

public class AdderThread1 extends Thread {

	Sum sum;
	int start;
	int end;

	public AdderThread1(Sum sum, int start, int end) {
		this.sum = sum;
		this.start = start;
		this.end = end;
	}

	@Override
	public void run() {
		for (int i = start; i <= end; i++) {
			sum.addNum(i);
		}

	}

}
package thread;

public class AdderThreadhMain2 {

	public static void main(String[] args) {

		Sum sum = new Sum();
		AdderThread1 t1 = new AdderThread1(sum, 1, 5000);
		AdderThread1 t2 = new AdderThread1(sum, 5001, 10000);
		
		t1.start();
		t2.start();
		
		try {
			t1.join();
			t2.join();			
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		System.out.println("1-100합 "+ sum.getNum());
	}

}

 

<출력>

1-100합 50005000

 

동기화블럭

public class Calculator {

	int opplCnt=0; // 몇번의 연산을 했나요?
	int opmiCnt=0;
	
	
	public int add(int n1, int n2) {
		synchronized (this) { // key
			opplCnt++;			
		}
//		opCnt++;	
		return n1+n2;
	}
	
	
	public int min(int n1, int n2) {
		synchronized (obj) { // 참조값이 달라서 다르다.
			opmiCnt++;
		}
//		opCnt++;
		return n1-n2;
	}
	
	Object obj = new Object(); // 새로운 동기화 키 생성
}

만약 opplCnt / opmiCnt가 아니라 똑같이 opCnt++;를 사용하면 똑같이 this(둘다같은거면OK)를 넣으면 된다

 

num1도 쓰고 num2도 쓰기 위해(효율성) 두개의 Key로 분리해 주는 것이라고 생각하면 되는듯하다.

 

– 버퍼 스트림 
•문자 입력 스트림으로부터 문자를 읽어 들이거나

문자 출력 스트림으로 문자를 내보낼 때 버퍼링을 함으로써 

   문자, 문자 배열, 문자열 라인 등을 보다 효율적으로 처리

 

예제1)

 

 

package io;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class ByteFileCopy {

	public static void main(String[] args) throws IOException {

		// 읽어올 대상 파일의 InputStream 인스턴스를 생성한다.

		InputStream in = new FileInputStream("org.pdf");

		// 출력 대상 파일의 OutpurStream 인스턴스 생성

		OutputStream out = new FileOutputStream("org_copy.pdf");

		// 필터스트림 인스턴스 생성
		BufferedInputStream bin = new BufferedInputStream(in, 1024 * 3);
		BufferedOutputStream bout = new BufferedOutputStream(out, 1024 * 3);

		int copyByte = 0; // 복사한 사이즈
		int bData = 0; // 원본에서 복사한 byte 사이즈의 데이터

		System.out.println("복사를 시작합니다.");

		while (true) {
			bData = in.read(); // 더이상 가져올 데이터가 없으면 -1을 반환

			if (bData == -1) {

				break;
			}
			out.write(bData); // 출력 : 파일에 바이터리 코드를 쓴다.
			copyByte++;
		}

		in.close(); // 스트림 인스턴스 소멸
		out.close();
		System.out.println("복사가 완료되었습니다.");
		System.out.println("복사된 사이즈 : " + copyByte + "byte");
	}
}

 

 

예제2)

 

 

package io;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class BufferedByteFileCopy {

	public static void main(String[] args) throws IOException  {

		
		// 읽어올 대상 파일의 InputStream 인스턴스를 생성한다.

			InputStream in = new FileInputStream("org.pdf");
			
		// 출력 대상 파일의 OutpurStream 인스턴스 생성
			
			OutputStream out = new FileOutputStream("org_copy.pdf");

		int copyByte=0; // 복사한 사이즈
		
		byte[] buf = new byte[1024]; // 1kb 버퍼생성
		int readLength = 0; // 얼마만큼 읽어왔는지.
		
		System.out.println("복사를 시작합니다.");
		
		while(true) {

			readLength = in.read(buf);
			
			if(readLength==-1) { 
				break;
			}

			out.write(buf,0,readLength);
			copyByte+= readLength;
		}
		
		in.close(); // 스트림 인스턴스 소멸
		out.close(); 
		System.out.println("복사가 완료되었습니다.");
		System.out.println("복사된 사이즈 : " + copyByte + "byte");
}
}
package io;

import java.io.File;

public class FileMove {

	public static void main(String[] args) {

		// File 클래스는 경로를 저장한다.
		// 파일의 경로, 폴더의 경로
		// 파일 또는 폴더의 속성을 변경하거나 삭제, 생성이 가능하다.
		
		// 현재 존재하는 파일의 경로를 생성
		File myFile = new File("C:"+File.separator+"myJava\\my.bin");
		
//		myFile.delete();
		
		if(!myFile.exists()) {
			System.out.println("원본 파일이 준비되어 있지 않습니다.");
			System.out.println("프로그램을 종료합니다.");
			return;
		}
		System.out.println("파일 존재");
		
		File reDir = new File("c:\\yourJava");
		reDir.mkdir(); // 해당 경로에 폴더가 있으면 그대로 유지, 없으면 생성
		System.out.println("폴더 생성 성공");
		
		//파일을 이동할 새로운 경로 생성
		File refile = new File(reDir, "Your.bin");
		System.out.println("파일 존재 유무 : " + refile.exists());
		
		//파일 이동
		myFile.renameTo(refile);
		
		if(refile.exists()) {
			System.out.println("파일 이동 성공");
		}
		
		
	}

}

예제1)

package io;

import java.io.Serializable;

public class Circle implements Serializable{
	
	//implements Serializable : 직렬화의 대상이다. 인스턴스 저장이 가능하다.
	// 직렬화를 하기 위해서는 반드시 해줘야함..
	
	int x;
	int y;
	double rad;
	
	public Circle(int x, int y, double r) {
		this.x=x;
		this.y=y;
		this.rad=r;
	}
	

	public void showCircleInfo() {
		System.out.printf("[%d,%d]", x,y);
		System.out.println("rad : " +  rad);
		
	}

}
package io;

import java.io.Serializable;

public class Circle2 implements Serializable {

	// implements Serializable : 직렬화의 대상이다. 인스턴스 저장이 가능하다.
	// 직렬화를 하기 위해서는 반드시 해줘야함..

	// transient Point p; 직렬화대상에서 제외
	Point p;
	double rad;

	public Circle2(int x, int y, double r) {
		p = new Point(x, y);
		this.rad = r;
	}

	public void showCircleInfo() {
		System.out.println("rad : " + rad);

	}

}
package io;

import java.io.Serializable;

public class Point implements Serializable {

	int x;
	int y;

	public Point(int x, int y) {
		this.x = x;
		this.y = y;

	}

}
package io;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class ObjectSerializable {

	public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
		
		// 인스턴스 저장을 위한 스트림 생성
		ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("Object.ser"));
		
		// 인스턴스를 저장
		out.writeObject(new Circle(1,1,2.4));
		out.writeObject(new Circle(2,2,4.8));
		out.writeObject(new String("String class implements Serializable"));
		// String 클래스도 직렬화 가능
		out.writeObject(new Circle2(3,3,6.9));
		
		out.close(); // 저장~!
		
		// 인스턴스 복원
		ObjectInputStream in = new ObjectInputStream(new FileInputStream("Object.ser"));
		
		
//		Circle c1 = (Circle) in.readObject(); // 형변환
		Object o1 = in.readObject();
		Circle c1 =null;
		if(o1 instanceof Circle) {
			c1 = (Circle)o1;
		}
		
		
		Circle c2 = (Circle) in.readObject();
		String str= (String) in.readObject();
		
		Object o2 = in.readObject();
		Circle2 c3=null;
		
		if(o2 instanceof Circle2) {
			c3= (Circle2)o2;
		}
		
		// 복원된 인스턴스 출력
		
		c1.showCircleInfo();
		c2.showCircleInfo();
		System.out.println(str);
		c3.showCircleInfo();
		
		
	}
}

예제2)

 

package io;

import java.beans.Transient;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class PersonInfo implements Serializable {

	String name;
	transient String secretInfo;
	int age;
	transient int secretNum;

	public PersonInfo(String name, String secretInfo, int age, int secretNum) {
		this.name = name;
		this.secretInfo = secretInfo;
		this.age = age;
		this.secretNum = secretNum;
	}

	public void showInfo() {
		System.out.println("name : " + name);
		System.out.println("secretInfo : " + secretInfo);
		System.out.println("age : " + age);
		System.out.println("secretNum : " + secretNum);

	}

	public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
		// 인스턴스 저장 스트림 생성
		ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("PersonInfo.ser"));

		PersonInfo info = new PersonInfo("김태형", "뽀선이애인", 24, 1);
		info.showInfo();

		// 인스턴스 저장
		out.writeObject(info);
		out.close();

		// 인스턴스 복원을 위한 스트림 생성
		ObjectInputStream in = new ObjectInputStream(new FileInputStream("PersonInfo.ser"));

		// 복원
		PersonInfo reInfo = (PersonInfo) in.readObject();

		// 복원된 인스턴스의 정보 출력
		reInfo.showInfo();

	}

}

–문자 스트림 


•유니코드로 된 문자를 입·출력 하는 스트림 
•2바이트를 입·출력 - 세계 모든 언어로 구성된 파일을 입·출력 하기에 적합 
•이미지, 동영상과 같은 바이너리 데이터는 입·출력 할 수 없음 
•문자 데이터만 입·출력 가능 

 

 

 

Reader의 대표적인 메소드

public int read() throws IOException
public abstract int read(char[] cbuf, int off, int len) throws IOException

Writer의 대표적인 메소드

public int write(int c) throws IOException

public abstract void write(char[] cbuf, int off, int len) throws IOException 

 

 

BufferedWriter

package io;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;

public class StringWriter {

	public static void main(String[] args) throws IOException {

		// 필터스트림 : 기본 스트림 writer가 필요하다.
		Writer writer = new FileWriter("String.txt");  // 기본스트림
		BufferedWriter out = new BufferedWriter(writer); // 필터스트림
		
		out.write("Cos ah ah I’m in the stars tonight");
		out.newLine();
		out.write("So watch me bring the fire and set the night alight");
		out.newLine();
		out.write("Shining through the city with a little funk and soul");
		out.newLine();
		out.write("So I’mma light it up like dynamite, woah");
		out.newLine();
		out.newLine();
		out.write("BTS - Dynamite");
		
		// 스트림닫기
		out.close();
		
	}

}

BufferedReader

package io;

import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.io.BufferedReader;

public class StringReader {

	public static void main(String[] args) throws IOException{
		
	
	// 문자 기반 기본 스트림 인스턴스 생성
	Reader reader = new FileReader("String.txt");
	// 필터스트림
	BufferedReader in = new BufferedReader(reader);
	
	// 한행의 문자열을 담을 변수
	
	String str=null;
	while(true) {
		//한줄씩 읽어 문자열을 반환, 없으면 null
		str=in.readLine();
		if(str==null) {
		break;
	}
		System.out.println(str);
	
	}
}
}

 

문자 필터 스트림 PrintWriter

package io;

import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

public class PrintWriterStream {

	public static void main(String[] args) throws IOException {

		PrintWriter out = new PrintWriter(new FileWriter("Print.txt"));
		
		out.printf("안녕하세요 저는 %d살 %s입니다.",12,"철수");
		out.println();
		out.print("저는 자바를 좋아합니다");
		out.println("IO 재미있네요.");
		out.close();
		
		System.out.println("파일작성 완료");
	}

}

'JAVA > basic' 카테고리의 다른 글

[ 입출력 ] 버퍼 스트림  (0) 2020.10.26
[ 입출력 ] File  (0) 2020.10.26
[ 입출력 ] 직렬화 (Serializable)  (0) 2020.10.26
[ 입출력 ] Stream / 바이트스트림  (0) 2020.10.26
Map <K, V> / HashMap <K, V> key-value  (0) 2020.10.23
[ 컬렉션 Collection<E> ] TreeSet  (0) 2020.10.23
[ 컬렉션 Collection<E> ] HashSet  (0) 2020.10.23

스트림(stream)이란?
- 데이터를 운반(입출력)하는데 사용되는 연결통로
- 연속적인 데이터의 흐름을 물(stream)에 비유해서 붙여진 이름
- 하나의 스트림으로 입출력을 동시에 수행할 수 없다.(단방향 통신)
- 입출력을 동시에 수행하려면, 2개의 스트림이 필요하다.

 

•자바의 스트림
–입·출력 장치와 프로그램을 연결하며, 이들 사이의 데이터 흐름을 처리하는 소프트웨어 모듈
–데이터를 처리하기 위한 공통된 방법을 제공함
–입력 스트림 : 입력 장치로부터 자바 프로그램으로 전달되는 데이터의 흐름 혹은 데이터 전송 소프트웨어 모듈
–출력 스트림 : 자바 프로그램에서 출력 장치로 보내는 데이터의 흐름 또는 데이터 전송 소프트웨어 모듈

 

자바 입·출력 스트림의 특징
–스트림은 FIFO 구조
• FIFO : 먼저 들어간 것이 먼저 나오는 형태 → 데이터의 순서가 바뀌지 않음
–스트림은 단방향
• 읽기, 쓰기가 동시에 되지 않음
• 읽는 스트림과 쓰는 스트림을 하나씩 열어 사용해야 함
–스트림은 지연될 수 있음
• 스트림은 넣어진 데이터가 처리되기 전까지는 스트림에 사용되는 스레드가 지연상태에 빠짐
• 네트워크 내에서는 데이터가 모두 전송되기 전까지 네트워크 스레드는 지연상태를 유지함

•InputStream 클래스의 대표적인 두 메소드

  public abstract int read() throws IOException

  public void close() throws IOException

 

•OutputStream 클래스의 대표적인 메소드

 public abstract void write(int b) throws IOException

 public void close() throws IOException

 

자바 입·출력 스트림의 종류


–바이트 스트림


•문자 단위/바이트 단위
•바이트 스트림은 1바이트를 입·출력 할 수 있는 스트림
•자바에서 입·출력 스트림을 통해 흘러가는 데이터의 기본 단위
•일반적으로 바이트로 구성된 파일을 처리하기에 적합

 

•바이트 스트림 클래스
–JAVA . IO 패키지 포함
–InputStream/OutputStream

 >추상 클래스로써 바이트 입·출력 스트림을 다루는 모든 클래스의 슈퍼 클래스
–FileInputStream/FileOutputStream 

 >파일로 부터 바이트 단위로 읽거나 저장하는 클래스

 >바이너리 파일을 입·출력을 할 때 사용

 

 

package io;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class ByteFileCopy {

	public static void main(String[] args) throws IOException  {

		
		// 읽어올 대상 파일의 InputStream 인스턴스를 생성한다.

			InputStream in = new FileInputStream("org.pdf");
			
		// 출력 대상 파일의 OutpurStream 인스턴스 생성
			
			OutputStream out = new FileOutputStream("org_copy.pdf");

			
		// 필터스트림 인스턴스 생성
		BufferedInputStream bin = new BufferedInputStream(in, 1024*3);
		BufferedOutputStream bout = new BufferedOutputStream(out, 1024*3);
		
		int copyByte=0; // 복사한 사이즈
		int bData=0; // 원본에서 복사한 byte 사이즈의 데이터
		
//		byte[] buf = new byte[1024]; // 1kb 버퍼생성
//		int readLength = 0; // 얼마만큼 읽어왔는지.
		
		System.out.println("복사를 시작합니다.");
		
		while(true) {
			bData = in.read(); // 더이상 가져올 데이터가 없으면 -1을 반환
//			readLength = in.read(buf);
			
			if(bData==-1) { 
//			if(readLength==-1) { 
				break;
			}
			out.write(bData); // 출력 : 파일에 바이터리 코드를 쓴다.
//			out.write(buf,0,readLength);
//			copyByte+= readLength;
			copyByte++;
		}
		
		in.close(); // 스트림 인스턴스 소멸
		out.close(); 
		System.out.println("복사가 완료되었습니다.");
		System.out.println("복사된 사이즈 : " + copyByte + "byte");
}
}

 

package Collection;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;

public class HashMapTest {

	public static void main(String[] args) {

		// Map : key-Value 형식으로 저장하는 객체
		// 대표적인 형식이 HashMap이다. HashMap<K, V>
		HashMap<Integer, String> map = new HashMap<Integer, String>();

		// 요소 추가 : put(T e)
		map.put(1, "김남준");
		map.put(2, "김석진");
		map.put(3, "민윤기");
		map.put(4, "정호석");
		map.put(5, "박지민");
		map.put(6, "김태형");
		map.put(7, "전정국");

		// 참조 : V get(K key)
		// put에서는 반복하는 Iterator가 없다
		// 그냥 하나 딱 뽑아쓰려고할 때 유용한 느낌

		System.out.println("1번 " + map.get(1));
		System.out.println("2번 " + map.get(2));
		System.out.println("3번 " + map.get(3));
		System.out.println("4번 " + map.get(4));
		System.out.println("5번 " + map.get(5));
		System.out.println("6번 " + map.get(6));
		System.out.println("7번 " + map.get(7));

		for (int i = 1; i < map.size(); i++) {
			System.out.print(map.get(i) + "\t");
		}

		// Set<Key Type>
		Set<Integer> set = map.keySet();
		Iterator<Integer> itr = set.iterator();
		
        System.out.println();
		while (itr.hasNext()) {
			int key = itr.next();
			System.out.println(key + "번 학생의 이름은 " + map.get(key));
		}

	}

}

<출력>

 

1번 김남준
2번 김석진
3번 민윤기
4번 정호석
5번 박지민
6번 김태형
7번 전정국
김남준 김석진 민윤기 정호석 박지민 김태형

1번 학생의 이름은 김남준
2번 학생의 이름은 김석진
3번 학생의 이름은 민윤기
4번 학생의 이름은 정호석
5번 학생의 이름은 박지민
6번 학생의 이름은 김태형
7번 학생의 이름은 전정국

 

 

<NavigableSet  / TreeMap에서만 사용가능>

- descendingInterator// Key값 내림차순 정렬

import java.util.Iterator;
import java.util.NavigableSet;
import java.util.TreeMap;

public class HashMapTest {

	public static void main(String[] args) {

		// Map : key-Value 형식으로 저장하는 객체
		// 대표적인 형식이 HashMap이다. HashMap<K, V>
		TreeMap<Integer, String> map = new TreeMap<Integer, String>();

		// 요소 추가 : put(T e)
		map.put(1, "김남준");
		map.put(2, "김석진");
		map.put(3, "민윤기");
		map.put(4, "정호석");
		map.put(5, "박지민");
		map.put(6, "김태형");
		map.put(7, "전정국");

		// NavigableSet<Key Type>
		NavigableSet<Integer> set = map.navigableKeySet();
		
		System.out.println("오름차순 출력...");
		Iterator<Integer> itr = set.iterator();
		while (itr.hasNext())
			System.out.println(map.get(itr.next()));

		System.out.println("내림차순 출력...");
		itr = set.descendingIterator(); // 내림차순 정렬
		while (itr.hasNext())
			System.out.println(map.get(itr.next()));
	}

}

< 출력 >

 

오름차순 출력...
김남준
김석진
민윤기
정호석
박지민
김태형
전정국


내림차순 출력...
전정국
김태형
박지민
정호석
민윤기
김석진
김남준

 

TreeSet<E> 클래스는 트리라는 자료구조를 기반으로 데이터를 저장한다.
데이터를 정렬된 순서로 저장하며, HashSet<E>와 마찬가지로 데이터의 중복저장 않는다.
정렬의 기준은 프로그래머가 직접 정의한다.

 

package Collection;

import java.util.Iterator;
import java.util.TreeSet;

public class TreeSetTest {

	public static void main(String[] args) {

		
		// Treeset : 트리 구조로 저장하는 자료구조. 2진트리

		// Treeset 인스턴스 생성
		TreeSet<Integer> tSet = new TreeSet<Integer>();
		

		tSet.add(1);
		tSet.add(5);
		tSet.add(2);
		tSet.add(4);
		tSet.add(3);
		tSet.add(2);
		
		System.out.println("Treeset 요소의 갯수 : " + tSet.size());
		
		Iterator<Integer> itr = tSet.iterator();
		
		while(itr.hasNext()){
			System.out.println(itr.next());
		}

	}

}

 

<출력>

 

Treeset 요소의 갯수 : 5
1
2
3
4
5

 

package Collection;

import java.util.Iterator;
import java.util.TreeSet;

public class Person implements Comparable<Person>{

	String name;
	int age;
	
	public Person(String name, int age) {
		this.name=name;
		this.age=age;
	}
	
	@Override
	public String toString() {
		return name+"("+age+")";
	}

	
	public int compareTo(Person o) {
//		if(age>o.age) {
//			return 1; // 양수반환 : 전달받은 객체의 값이 작을 때
//		}else if (age<o.age) {	
//			return -1; // 음수반환
//		}else {
		 // return age-o.age; // 작은수 > 큰수
		return o.age-age; // 큰수 > 작은수
	}
	
	

	

	public static void main(String[] args) {
		
		TreeSet<Person> tSet = new TreeSet<Person>();
		
		tSet.add(new Person("김태형", 24));
		tSet.add(new Person("박지민", 24)); // 그와중에 age가 같아서 중복이라 지워진다~~!!
		tSet.add(new Person("전정국", 23));
		tSet.add(new Person("김석진", 27));

		Iterator<Person> itr = tSet.iterator();
		
		while(itr.hasNext()) {
			System.out.println(itr.next());
			
		}
		
}
}

 

<출력>

 

김석진(27)
김태형(24)
전정국(23)

List<E>를 구현하는 클래스들과 달리 Set<E>를 구현하는 클래스들은 데이터의 중복저장을 허용하지 않는다.

(단, 동일 데이터에 대한 기준은 프로그래머가 정의)

 

 

package Collection;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class SetTest {

	public static void main(String[] args) {

		// HashSet 인스턴스 생성 : 인스턴스를 저장하기 위한 저장 공간 생성
		// set : 집합, 저장순서 유지하지않는다.
		
		Set<String> set = new HashSet<String>();
		
		set.add("First");
		set.add("Second");
		set.add("Third");
		set.add("First");   // 중복이라 저장되지 않는다.
		

		System.out.println("set 요소의 개수 : "+ set.size());
		
		Iterator<String> itr=set.iterator();
		while(itr.hasNext()) {
			System.out.println(itr.next());
		}
	}

}

<출력>

 

set 요소의 개수 : 3
Second
Third
First

 

// Set<e>는 저장하는 순서를 가지지 않기 때문에 
// 일괄처리를 위해서는 Iterator<E> 인스턴스를 이용해서 처리한다.
// Collection<E>에는 Iterater() 메서드를 가지고 있고 Iterator<E>를 반환한다.

 

 

HashSet<E>클래스의 동등비교

String에는 Hashcode() 가 있어서 지 알아서 중복 분류해주지만 나머지는 해시코드를 만들어줘야한다

package Collection;

public class SimpleNumber {

	int num;

	public SimpleNumber(int num) {
		this.num = num;
	}

	@Override
	public String toString() {
		return String.valueOf(num);
	}
	
}
package Collection;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class SimpleNumberMain {

	public static void main(String[] args) {

		// set  인스턴스 생성		
		Set<SimpleNumber> set=new HashSet<SimpleNumber>();
		
		set.add(new SimpleNumber(10));
		set.add(new SimpleNumber(20));
		set.add(new SimpleNumber(10));
		
		System.out.println("Set 요소의 개수 : "+set.size());
		
		Iterator<SimpleNumber> itr = set.iterator();
		
		while(itr.hasNext()) {
			System.out.println(itr.next());
		}

	}

}

<출력>

 

Set 요소의 개수 : 3
10
10
20

 

 

<SimpleNumber  수정>

쉬프트 알트 o > gernerate hashcode() and equals()

package Collection;

public class SimpleNumber {

	int num;

	
	// Set 동등 비교를 위한 Hashcode(), equals() 오버라이딩
	
	@Override
	public int hashCode() {
//		final int prime = 31;
//		int result = 1;
//		result = prime * result + num;
		return num%3; // 0 or 1 or 2
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj) // 참조 주소값 == 전달받은 참조 주소값
			return true;
		if (obj == null) // 들어오는 객체가 null  ex) set.add(null)인 경우
			return false;
		if (getClass() != obj.getClass()) // 클래스 이름비교, 같은 타입인가
			return false;
		SimpleNumber other = (SimpleNumber) obj;
		if (num != other.num)
			return false;
		return true;
	}

	public SimpleNumber(int num) {
		this.num = num;
	}

	@Override
	public String toString() {
		return String.valueOf(num);
	}
	
}

< 출력 >

 

Set 요소의 개수 : 2
10
20

반복자를 사용하면, 컬렉션 클래스의 종류에 상관없이 동일한 형태의 데이터 참조방식을 유지할 수 있다.
따라서 컬렉션 클래스의 교체에 큰 영향이 없다.
컬렉션 클래스별 데이터 참조 방식을 별도로 확인할 필요가 없다.

 

package Collection;

import java.util.ArrayList;
import java.util.Iterator;

public class IteraorTest {

	public static void main(String[] args) {
		
		ArrayList<String> list = new ArrayList<String>();
		
		list.add("First");
		list.add("second");
		list.add("Third");
		list.add("Fourth");
		
		// Iterator<E> 인스턴스 생성 : Iterator 메서드 호출
		System.out.println("요소 출력");
		
		Iterator<String> itr=list.iterator();
		
		//hasNext(), Next(), remove();
		while(itr.hasNext()) {
			String str=itr.next(); // hasNext(있다면)  str(받아서)
			System.out.println(str); // print(출력)
			
			if(str.compareTo("Third")==0) {
				itr.remove();
				
			}
		}
		
		System.out.println("요소 삭제 후 요소 출력");
		
		itr = list.iterator();
		while(itr.hasNext()) {
			System.out.println(itr.next());
		}
	}

}

'JAVA > basic' 카테고리의 다른 글

Map <K, V> / HashMap <K, V> key-value  (0) 2020.10.23
[ 컬렉션 Collection<E> ] TreeSet  (0) 2020.10.23
[ 컬렉션 Collection<E> ] HashSet  (0) 2020.10.23
[ 컬렉션 Collection<E> ] ArrayList  (0) 2020.10.23
[ 컬렉션 Collection<E> ] 컬렉션 프레임워크  (0) 2020.10.22
generic / 제네릭  (0) 2020.10.22
예외처리 / Exception  (0) 2020.10.21

ArrayList<E>의 단점 

• 저장소의 용량을 늘리는 과정에서 많은 시간이 소요된다. 
• 데이터의 삭제에 필요한 연산과정이 매우 길다. 

ArrayList<E>의 장점
• 데이터의 참조가 용이해서 빠른 참조가 가능하다.

// 근데 어차피 대부분 ArrayList를 쓴다고 한다 (❌LinkedList)

 

ArrayList<int> arr=new ArrayList<int>( ); error
LinkedList<int> link=new LinkedList<int>( ); error

기본 자료형 정보를 이용해서 제네릭 인스턴스 생성 불가능!
따라서 Wraper 클래스를 기반으로 컬렉션 인스턴스를 생성한다. (Int 말고 Integer⭕)

 

 

 

 

- ArrayList <어떤Type> 이름

 

형식 기능 
이름.get(index) index에 저장된 저장값 불러오기
이름.size 저장된 요소의 갯수
이름.remove(index) index에 저장된 것 삭제
이름.add(추가할값)
추가
이름.add(index, 추가할값)
index에 추가할 값을 추가 (그 뒤는 index 하나씩 알아서 뒤로 밀림)
이름.containts(어떤값) 어떤값이 추가하는지 true/false 반환
이름.set(index,수정값) index 자리에 있는 값을 수정값으로 수정
이름.indexOf(특정값) 특정값이 잇는 index를 반환
이름.isEmpty(); 값을 가지고 있으면 true 아니면 false
이름clear(); 모든 원소 삭제

 

package Collection;

import java.util.ArrayList;

public class ArrayListTest {

	public static void main(String[] args) {

		// 인스턴스 저장을 목적으로 하는 클래스
		// List<E> : 저장 순서 유지 (반복문이용 용이), 중복저장 허용

		//ArrayList<Integer> list = new ArrayList<Integer>();
		//List<Integer> list = new ArrayList(); 
		List<Integer> list = new ArrayList<Integer>();
		
		list.add(1);
		list.add(2);
		list.add(3);
		list.add(4);

		System.out.println("list의 첫번째 요소의 값 : " + list.get(0));
		System.out.println("list 요소의 갯수 : " + list.size());

		System.out.println("list 출력");
		for (Integer i : list) {
			System.out.println(i);
		}
		
		// 삭제
		list.remove(2);
		
		System.out.println("삭제 후 list 출력");
		for (Integer i : list) {
			System.out.println(i);
		}
		
		
	}

}

<출력>

 

list의 첫번째 요소의 값 : 1
list 요소의 갯수 : 4
list 출력
1
2
3
4
삭제 후 list 출력
1
2
4

 

 

'JAVA > basic' 카테고리의 다른 글

[ 컬렉션 Collection<E> ] TreeSet  (0) 2020.10.23
[ 컬렉션 Collection<E> ] HashSet  (0) 2020.10.23
[ 컬렉션 Collection<E> ] Iterator  (0) 2020.10.23
[ 컬렉션 Collection<E> ] 컬렉션 프레임워크  (0) 2020.10.22
generic / 제네릭  (0) 2020.10.22
예외처리 / Exception  (0) 2020.10.21
예외처리 / throw  (0) 2020.10.21

컬렉션 프레임워크의 개념


컬렉션 프레임워크(collection framework)란?

자바에서 컬렉션 프레임워크(collection framework)란 다수의 데이터를 쉽고 효과적으로 처리할 수 있는 표준화된 방법을 제공하는 클래스의 집합을 의미합니다, 즉, 데이터를 저장하는 자료 구조와 데이터를 처리하는 알고리즘을 구조화하여 클래스로 구현해 놓은 것입니다.  이러한 컬렉션 프레임워크는 자바의 인터페이스(interface)를 사용하여 구현됩니다.


컬렉션 프레임워크 주요 인터페이스

 

컬렉션 프레임워크에서는 데이터를 저장하는 자료 구조에 따라 다음과 같은 핵심이 되는 주요 인터페이스를 정의하고 있습니다.

 

1. List 인터페이스

2. Set 인터페이스

3. Map 인터페이스

 

이 중에서 List와 Set 인터페이스는 모두 Collection 인터페이스를 상속받지만, 구조상의 차이로 인해 Map 인터페이스는 별도로 정의됩니다. 따라서 List 인터페이스와 Set 인터페이스의 공통된 부분을 Collection 인터페이스에서 정의하고 있습니다. 자바 컬렉션 프레임워크의 주요 인터페이스에 대한 더 자세한 사항은 다음 페이지를 참고하면 됩니다.

 

Java Documentation : The Collections Framework =>


주요 인터페이스 간의 상속 관계

자바에서 컬렉션 프레임워크를 구성하고 있는 인터페이스 간의 상속 관계는 다음 그림과 같습니다.

 

 

위의 그림에서 <E>나 <K, V>라는 것은 컬렉션 프레임워크를 구성하는 모든 클래스가 제네릭으로 표현되어 있음을 알려줍니다.

 


주요 인터페이스의 간략한 특징

 

자바에서 컬렉션 프레임워크를 구성하고 있는 주요 인터페이스의 간략한 특징은 다음과 같습니다.

 

 

List<E> 순서가 있는 데이터의 집합으로, 데이터의 중복을 허용함. Vector, ArrayList, LinkedList, Stack, Queue
Set<E> 순서가 없는 데이터의 집합으로, 데이터의 중복을 허용하지 않음. HashSet, TreeSet
Map<K, V>

키와 값의 한 쌍으로 이루어지는 데이터의 집합으로, 순서가 없음.

이때 키는 중복을 허용하지 않지만, 값은 중복될 수 있음.

HashMap, TreeMap, Hashtable, Properties

컬렉션 클래스(collection class)

 

컬렉션 프레임워크에 속하는 인터페이스를 구현한 클래스를 컬렉션 클래스(collection class)라고 합니다. 컬렉션 프레임워크의 모든 컬렉션 클래스는 List와 Set, Map 인터페이스 중 하나의 인터페이스를 구현하고 있습니다. 또한, 클래스 이름에도 구현한 인터페이스의 이름이 포함되므로 바로 구분할 수 있습니다. Vector나 Hashtable과 같은 컬렉션 클래스는 예전부터 사용해 왔으므로, 기존 코드와의 호환을 위해 아직도 남아 있습니다. 하지만 기존에 사용하던 컬렉션 클래스를 사용하는 것보다는 새로 추가된 ArrayList나 HashMap 클래스를 사용하는 것이 성능 면에서도 더 나은 결과를 얻을 수 있습니다. 다음 예제는 ArrayList 클래스를 이용하여 리스트를 생성하고 조작하는 예제입니다.

 

 

예제

import java.util.*;

public class Collection01 {

    public static void main(String[] args) {

        // 리스트 생성

        ArrayList<String> arrList = new ArrayList<String>();



        // 리스트에 요소의 저장

        arrList.add("넷");

        arrList.add("둘");

        arrList.add("셋");

        arrList.add("하나");



        // 리스트 요소의 출력

        for(int i = 0; i < arrList.size(); i++) {

            System.out.println(arrList.get(i));

        }

    }

}

실행 결과

 

하나


Collection 인터페이스

 

List와 Set 인터페이스의 많은 공통된 부분을 Collection 인터페이스에서 정의하고, 두 인터페이스는 그것을 상속받습니다. 따라서 Collection 인터페이스는 컬렉션을 다루는데 가장 기본적인 동작들을 정의하고, 그것을 메소드로 제공하고 있습니다.  Collection 인터페이스에서 제공하는 주요 메소드는 다음과 같습니다.

 

메소드설명

boolean add(E e) 해당 컬렉션(collection)에 전달된 요소를 추가함. (선택적 기능)
void clear() 해당 컬렉션의 모든 요소를 제거함. (선택적 기능)
boolean contains(Object o) 해당 컬렉션이 전달된 객체를 포함하고 있는지를 확인함.
boolean equals(Object o) 해당 컬렉션과 전달된 객체가 같은지를 확인함.
boolean isEmpty() 해당 컬렉션이 비어있는지를 확인함.
Iterator<E> iterator() 해당 컬렉션의 반복자(iterator)를 반환함.
boolean remove(Object o) 해당 컬렉션에서 전달된 객체를 제거함. (선택적 기능)
int size() 해당 컬렉션의 요소의 총 개수를 반환함.
Object[] toArray() 해당 컬렉션의 모든 요소를 Object 타입의 배열로 반환함.

 


'JAVA > basic' 카테고리의 다른 글

[ 컬렉션 Collection<E> ] HashSet  (0) 2020.10.23
[ 컬렉션 Collection<E> ] Iterator  (0) 2020.10.23
[ 컬렉션 Collection<E> ] ArrayList  (0) 2020.10.23
generic / 제네릭  (0) 2020.10.22
예외처리 / Exception  (0) 2020.10.21
예외처리 / throw  (0) 2020.10.21
예외처리 / try-catch-finally  (0) 2020.10.21

1.

package generic;

public class Apple {

	private int weight; // 사과의 무게
	
	Apple(int weight){
		this.weight= weight;
	}
	
	public void showWeight() {
		System.out.println("사과의 무게 : " + weight);
	}
}
package generic;

public class Orange {

	private int sugarContent; // 오렌지 당도
	
	Orange(int sugar){
		this.sugarContent=sugar;
	}
	
	public void showsugarContent() {
		System.out.println("오렌지의 당도 : " + sugarContent);
	}
}
package generic;

public class AppleBox {
	
	Apple apple;
	
	public void store(Apple apple) {
		this.apple=apple;
	}
	
	public Apple PullOut() {
		return apple;
	}
}
package generic;

public class OrangeBox {
	
	Orange orange;
	
	public void store(Orange orange) {
		this.orange=orange;
	}
	
	public Orange PullOut() {
		return orange;
	}
}
package generic;

public class FruitBoxMain {

	public static void main(String[] args) {

		AppleBox appleBox = new AppleBox();
		appleBox.store(new Apple(10));
		Apple apple = appleBox.PullOut();
		
		apple.showWeight();
		
		OrangeBox orangeBox = new OrangeBox();
		// orangeBox.store(new String("오렌지"));
		orangeBox.store(new Orange(100));
		Orange orange = orangeBox.PullOut();
		
		orange.showsugarContent();
	}

}

2. 

fruitBox를 만들어서 사과와 오렌지를 각각 집어넣어줄 수 있지만,

아무거나 들어가도 빨간줄이 생기지 않지만, 실행하면 에러가 난다.

package generic;

public class FruitBox {
	
	Object fruit;
	
	public void store(Object fruit) {
		this.fruit=fruit;
	}
	
	public Object PullOut() {
		return fruit;
	}

}

 

package generic;

public class FruitBoxMain {

	public static void main(String[] args) {

		
		FruitBox box1 = new FruitBox();
		box1.store(new Apple(100));
		Apple apple = (Apple)box1.PullOut();
		apple.showWeight();
		
		FruitBox box2 = new FruitBox();
		box2.store("Apple"); // Apple 타입만 들어가야 한다. (아무거나 들어가도 ㅇㅋ인게 문제점..)
		Orange orange = (Orange)box2.PullOut();//형변환
		orange.showsugarContent();
		
	}

}

3.

제네릭을 이용해 FuritBox<T>를 생성해주면

형변환도 필요없고 알아서 올바르지 않은 타입이 들어가면 빨간줄이 생긴다.

package generic;

public class FruitBox <T> { // T > Apple / Orange
	
	T fruit; // Apple fruit
	
	public void store(T fruit) { // store(Apple fruit)
		this.fruit=fruit;
	}
	
	public T PullOut() { // public Apple PullOut()
		return fruit;
	}

}
package generic;

public class FruitBoxMain {

	public static void main(String[] args) {

		
		FruitBox<Apple> box1 = new FruitBox<Apple>();
		// box1.store("Apple"); 에러남
		box1.store(new Apple(10));
		Apple apple = box1.PullOut();
		apple.showWeight();
		
		FruitBox<Orange> box2 = new FruitBox<Orange>();
		// box2.store(new Apple(10)); // Orange만 들어갈 수 있게 됨
		box2.store(new Orange(100));		
		Orange orange = box2.PullOut(); //형변환도필요없다.
		orange.showsugarContent();
		
	}

}

4.

FruitBox<T>에 초기화 생성자를 추가하면 더욱 편리하다.

package generic;

public class FruitBox<T> { // T > Apple / Orange
	
	T fruit; // Apple fruit
	
	FruitBox(T fruit){   // FruitBox(Apple fruit){
		this.fruit=fruit;
		
	}
	
	public void store(T fruit) { // store(Apple fruit)
		this.fruit=fruit;
	}
	
	public T PullOut() { // public Apple PullOut()
		return fruit;
	}

}
package generic;

public class FruitBoxMain {

	public static void main(String[] args) {

		
		FruitBox<Apple> box1 = new FruitBox<Apple>(new Apple(10));
		Apple apple = box1.PullOut();
		apple.showWeight();
		
		FruitBox<Orange> box2 = new FruitBox<Orange>(new Orange(100));
		Orange orange = box2.PullOut(); //형변환도필요없다.
		orange.showsugarContent();
		
	}

}

예외클래스

docs.oracle.com/javase/8/docs/api/java/lang/Exception.html

Exception
    |
    |--- IOException
    |--- ClassNotFoundException
    |--- ...
    |--- RuntimeException
            |--- ArithmeticException
            |--- ClassCastException
            |--- NullPointerException
            |--- ...
            |--- IndexOutOfBoundsException
InputMismatchException 타입이 맞지 않을때 ex) int 인데 숫자가 아닌 다른 것이 입력되었을 때
ArithmeticException 산술연산 에러 ex) 나누는 수가 0일 때 (10/0)
NullPointerException 참조값이 없는 경우
ArrayIndexOutOfBoundsException 배열의 범위에서 인덱스 값을 벗어난 경우
ClassCastException 적절치 못하게 클래스를 형변환 하는 경우
NegativeArraySizeException 배열의 크기가 음수값인 경우
OutOfMemoryException 사용 가능한 메모리가 없는 경우
NoClassDefFoundException 원하는 클래스를 찾지 못한 경우
NumberFormatExcpeion 문자열을 숫자로 변경할 때 숫자가 변환될 수 없는 문자가 포함되어있음
실행 예외 (RuntimeException)
  • 예외가 발생하면 JVM은 해당하는 실행 예외 객체를 생성
  • 실행 예외는 컴파일러가 예외 처리 여부를 확인하지 않음. 따라서 개발자가 예외 처리 코드의 추가 여부를 결정
  • 대표적인 실행 예외 예
실행 예외 발생 이유
ArithmeticException 0으로 나누기와 같은 부적절한 산술 연산을 수행할 때 발생
IllegalArgumentException 메서드에 부적절한 인수를 전달할 때 발생
IndexOutOfBoundsException 배열, 벡터 등에서 범위를 벗어난 인덱스를 사용할 때 발생한다.
NoSuchElementException 요구한 원소가 없을 때 발생한다.
NullPointerException null 값을 가진 참조 변수에 접근할 때 발생한다.
NumberFormatException 숫자로 바꿀 수 없는 문자열을 숫자로 변환하려 할 때 발생한다.
일반 예외
  • 컴파일러는 발생할 가능성을 발견하면 컴파일 오류를 발생
  • 개발자는 예외 처리 코드를 반드시 추가
  • 대표적인 일반 예외 예
일반 예외 발생 이유
ClassNotFoundException 존재하지 않는 클래스를 사용하려고 할 때 발생한다.
InterruptedException 인터럽트 되었을 때 발생한다.
NoSuchFieldException 클래스가 명시한 필드를 포함하지 않을 때 발생한다.
NoSuchMethodException 클래스가 명시한 메서드를 포함하지 않을 때 발생한다.
IOException 데이터 읽기 같은 입출력 문제가 있을 때 발생한다.

 

'JAVA > basic' 카테고리의 다른 글

[ 컬렉션 Collection<E> ] ArrayList  (0) 2020.10.23
[ 컬렉션 Collection<E> ] 컬렉션 프레임워크  (0) 2020.10.22
generic / 제네릭  (0) 2020.10.22
예외처리 / throw  (0) 2020.10.21
예외처리 / try-catch-finally  (0) 2020.10.21
인터페이스 / interface / implements  (0) 2020.10.20
추상클래스 / abstract class  (0) 2020.10.20
Throwable 클래스의 주요 메서드
메서드 설명
public String getMessage() Throwable 객체의 자세한 메시지를 반환한다.
public String toString() Throwable 객체의 간단한 메시지를 반환한다.
public void printStackTrace() Throwable 객체와 추적 정보를 콘솔 뷰에 출력한다.

프로그래머가 직접 정의하는 예외의 상황

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package FirstJava;
 
public class ExcepthionThrow {
 
    public static void main(String[] args) {
        
        
        try {
            
            
            // 프로그래머가 강제로 예외를 발생시킨다.
            // 예외 클래스의 인스턴스 생성
            Exception e = new Exception("강제로 발생한 예외");
            // 예외발생
            throw e;
            
        }catch (Exception e){
            System.out.println(e.getMessage());
            e.printStackTrace(); // 예외발생 순서
        }
        System.out.println("프로그램 종료");
    }
 
}
 
cs

예제1)

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package FirstJava;
 
public class AgeInputException extends Exception{
    
    int age;
    
    public AgeInputException(int age) {
        super("유효하지 않은 나이가 입력되었습니다");
        this.age=age;
    }
 
    @Override
    public String toString() {
        return "AgeInputException [age=" + age + ", getMessage()=" + getMessage() + "]";
    }
 
 
 
}
 
cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package FirstJava;
 
import java.util.Scanner;
 
public class ProgrammerDefineException {
 
    public static void main(String[] args) throws AgeInputException {
 
        System.out.println("나이를 입력하세요");
        try {
        int age = readAge();
        System.out.println("나이는 "+ age + "세 입니다.");
        } catch(AgeInputException e) {
            System.out.println(e); // tostring()
        }
    
 
    }
 
    public static int readAge() throws AgeInputException{
        //throws AgeInputException
        //readAge 메서드 내에서 발생하는 예외중에
        //AgeInputException 타입의 예외가 발생하면
        //readAge()메서드를 호출한 쪽으로 전달
        Scanner sc = new Scanner(System.in);
        int age=sc.nextInt();
        // 논리적인 오류에 대한 예외 발생
        if(age<=0) {
            AgeInputException ae=new AgeInputException(age);
            throw ae;
        }
        return age;
    }
}
 
cs

 

  • if else와 달리 try-catch는 블럭내에 포함된 문장이 하나여도 {} 를 생략할 수 없다.
  • try 블럭 다음에는 여러 종류의 예외를 처리할 수 있도록 여러개의 catch블럭을 사용할 수 있다.
  • catch 내에 또 다른 try-catch 블럭을 사용할 수 있는데 이때는 다음과 같이 변수 e를 중복해서 사용할 수 없다.
  • 하나의 try 문에서 여러 개의 예외가 발생할 수 있지만 동시에 발생하지는 않음
  • 하나의 예외가 발생하면 즉시 try 블록의 실행을 멈추고 해당 catch 블록으로 이동
  • 예외 발생 여부와 관계없이 무조건 수할 실행문이 있다면 try~catch 문에 finally 블록 추가
  • 다중 catch 블록일 때 try 블록에서 예외가 발생하면 발생한 예외를 catch 블록 순서대로 비교
  • 앞에 있는 catch 블록의 예외 객체가 나중 catch 블록 예외 객체의 부모라면 앞에 있는 catch 블록이 먼저 가로챔 -> 컴파일러는 오류를 발생시킴
  • 구체적인 예외를 먼저 처리해야 함.

 

  • printStackTrace(): 예외발생 당시의 호출스택에 있었던 메서드의 정보와 예외 메시지를 화면에 출력
  • getMessage(): 발생한 예외클래스의 인스턴스에 저장된 메시지를 얻을 수 있다.

Try-catch 문의 실행순서

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 
class ExceptionEx {
    public static void main(String args[]) { // 0으로 나눠서 고의로 ArithmeticException을 발생시킨다.
        System.out.println("try~catch 실행 순서");
        System.out.println(1);
        System.out.println(2);
        try {
            System.out.println(3);
            System.out.println(0 / 0);
            System.out.println(4); // 실행되지 않는다.
        } catch (ArithmeticException ae) {
            System.out.println(5);
        } // try-catch의 끝
        System.out.println(6);
    } // main메서드의 끝
}


cs

rebeccacho.gitbooks.io/java-study-group/content/chapter8.html

 

Chapter 8 예외처리(Exception Handling) | Java Study Group

 

rebeccacho.gitbooks.io

butter-shower.tistory.com/87

 

[Java] 예외처리 - try~catch 문, throws문, 예외의 종류

오류의 종류 에러 (Error) 개발자가 해결할 수 없는 치명적인 오류 하드웨어의 잘못된 동작 또는 고장으로 인한 오류 에러가 발생되면 프로그램 종료 정상 실행 상태로 돌아갈 수 없음 예외 (Excepti

butter-shower.tistory.com

'JAVA > basic' 카테고리의 다른 글

generic / 제네릭  (0) 2020.10.22
예외처리 / Exception  (0) 2020.10.21
예외처리 / throw  (0) 2020.10.21
인터페이스 / interface / implements  (0) 2020.10.20
추상클래스 / abstract class  (0) 2020.10.20
오버라이딩 Override / Overriding & 다형성  (0) 2020.10.16
상속 / extends  (0) 2020.10.15

 

  • 일종의 추상클래스, 추상클래스보다 추상화 정도가 높다
  • 실제로 구현된 것이 전혀 없는 기본 설계도
  • 추상메서드와 상수만을 멤버로 가질 수 있다
  • 인스턴스를 생성할 수 없고, 클래스 작성에 도움을 줄 목적으로 작성
  • 미리 정해진 규칙에 맞게 구현하도록 표준을 제시하는데 사용된다.
  • 클래스처럼 상속 가능 / 다중상속 허용
  • Object클래스와 같은 최고 조상이 없다

 

예제1

 

예제2) 인터페이스 내에 선언된 변수는 무조건 public static final로 선언된다.

원래 case 1: case 2: - 같은 형식이었는데 좀 더 알아보기 쉽게 이렇게 바꿀 수도 있다.

 

예제2

 

 

 

인터페이스를 이용한 마킹의 효과

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package Oct17;
 
public class interfaceMark {
 
    public static void main(String[] args) {
 
        PointOne pos1 = new PointOne(11);
        PointTwo pos2 = new PointTwo(22);
        PointOne pos3 = new PointOne(33);
        PointTwo pos4 = new PointTwo(44);
        String test = "test";
        
        ClassPrinter.print(pos1);
        ClassPrinter.print(pos2);
        ClassPrinter.print(pos3);
        ClassPrinter.print(pos4);
        ClassPrinter.print(test);
    }
 
}
 
interface UpperCasePrintable {
    // 마킹하려고하는 건 거의 ~able로 이름을 만듦
 
}
 
class PointOne implements UpperCasePrintable {
    private int xPos;
    private int yPos;
 
    PointOne(int x, int y) {
        this.xPos = x;
        this.yPos = y;
 
    }
 
    @Override
    public String toString() {
        return "[x pos: " + xPos + ", y pos : " + yPos + "]";
    }
}
 
class PointTwo {
    private int xPos;
    private int yPos;
 
    PointTwo(int x, int y) {
        this.xPos = x;
        this.yPos = y;
    }
 
    @Override
    public String toString() {
        return "[x pos: " + xPos + ", y pos : " + yPos + "]";
    }
 
}
 
class ClassPrinter {
    public static void print(Object obj) {
        String str=obj.toString();
        
        // UppercasePrintable 형변환가능여부를 확인 > 대문자로 변경
        if(obj instanceof UpperCasePrintable) {
            str = str.toUpperCase();
        }
        
        System.out.println(str);
            
    }
}
cs

 

 

 

 

'JAVA > basic' 카테고리의 다른 글

예외처리 / Exception  (0) 2020.10.21
예외처리 / throw  (0) 2020.10.21
예외처리 / try-catch-finally  (0) 2020.10.21
추상클래스 / abstract class  (0) 2020.10.20
오버라이딩 Override / Overriding & 다형성  (0) 2020.10.16
상속 / extends  (0) 2020.10.15
[Singleton] 싱글톤 / 싱글턴 패턴  (0) 2020.10.15

 클래스가 설계도라면 추상클래스는 ‘미완성 설계도’ 

  • 완성된 설계도가 아니므로 인스턴스를 생성할 수 없다.  
  • 다른 클래스를 작성하는데 도움을 줄 목적으로 작성된다
  • 일반 메서드가 추상메서드를 호출할 수 있다 (호출 시 선언부 필요)
  •  

 

'JAVA > basic' 카테고리의 다른 글

예외처리 / throw  (0) 2020.10.21
예외처리 / try-catch-finally  (0) 2020.10.21
인터페이스 / interface / implements  (0) 2020.10.20
오버라이딩 Override / Overriding & 다형성  (0) 2020.10.16
상속 / extends  (0) 2020.10.15
[Singleton] 싱글톤 / 싱글턴 패턴  (0) 2020.10.15
getter / setter  (0) 2020.10.15

//출력

볼륨 크기 : 0
베이스의 크기 0

 

 

super 키워드를 넣으면 원래기능도 함께 할 수 있다.

 

@override 

주해(annotation)를 사용하면 컴파일러에게 수퍼 클래스의 메소드를 오버라이드 하려고 한다는 것을 알려줄 수 있다.

만약 컴파일러가 수퍼 클래스에 그러한 메소드가 존재하지 않는다는 것을 감지하면 오류를 알려준다

만약에 ShowCurrentState()라고 오타를 내면 오버라이딩이 아니라 새로운 메서드가 생성되어버리는데,

ShowCurrentState()가 존재하지 않아서 문제 있다고 알려준다. ㄳㄳ

 

오버라이딩의 조건   

1. 선언부가 같아야 한다.(이름, 매개변수, 리턴타입)   

2. 접근제어자를 좁은 범위로 변경할 수 없다. 

- 조상의 메서드가 protected라면, 범위가 같거나 넓은 protected나 public으로 만 변경할 수 있다. 

ex) BaseEnSpeaker에서 클래스에서  Private void showCurrentState()로 생성불가

    (조상메서드는 default이므로)

3. 조상클래스의 메서드보다 많은 수의 예외를 선언할 수 없다. 

 

오버로딩과 오버라이딩

 

오버로딩 : 기존에 없는 새로운 메서드를 정의하는 것 (New)

오버라이딩 : 상속받은 메서드의 내용을 변경하는 것 (Change, Modify)

 

 

 

 

'JAVA > basic' 카테고리의 다른 글

예외처리 / try-catch-finally  (0) 2020.10.21
인터페이스 / interface / implements  (0) 2020.10.20
추상클래스 / abstract class  (0) 2020.10.20
상속 / extends  (0) 2020.10.15
[Singleton] 싱글톤 / 싱글턴 패턴  (0) 2020.10.15
getter / setter  (0) 2020.10.15
접근제어 [ private / public / protected / default ]  (0) 2020.10.15

class 자손클래스 extends 조상클래스/부모클래스

▶ 상속이란? 

- 기존의 클래스를 재사용해서 새로운 클래스를 작성하는 것.

- 두 클래스를 조상과 자손으로 관계를 맺어주는 것.

- 자손의 멤버개수는 조상보다 적을 수 없다.(같거나 많다.)

 

- 공통부분은 조상에서 관리하고 개별부분은 자손에서 관리한다.

- 조상의 변경은 자손에 영향을 미치지만, 자손의 변경은 조상에 아무런 영향을 미치지 않는다.

 

  • 여기서 중요한 사실은 하위클래스의 생성자 내에서 상위클래스의 생성자호출을 통해서 상위 클래스의 인스턴스 멤버를 초기화 한다는 점이다!
  • 하위 클래스의 생성자는 상위클래스의 인스턴스 변수를 초기화할 데이터까지  자로 전달받아야 한다!
  • 하위 클래스의 생성자는 상위 클래스의 생성자 호출을 통해서 상위 클래스의  스턴스 변수를 초기화한다!
  • 키워드 super는 상위 클래스의 생성자 호출에 사용된다. Super와 함께 표시된 전달되는 인자의 수와 자료형을 참조하여 호출할 생성자가 결정 된다!

Child2에서는 새로운 String 변수를 추가해줌 (name)

GrandChild에서는 부모클래스인 Child2의 변수 name을 사용하기 위해 super를 사용함.

여기서 super는 Child2를 의미한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package Oct15;
 
public class CarMain {
 
    public static void main(String[] args) {
        
        //클래스멤버도 상속의 대상이다. 클래스 멤버는 한번만 생성/ 자손클래스의 이름으로도 참조, 호출이가능하다.
        System.out.println(Car.name);
        System.out.println(HybridCar.name);
        
        Car car1 = new Car(100);
        HybridCar car2 = new HybridCar(100,50);
        HybridWaterCar car3 = new HybridWaterCar(100,50,20);
 
        car3.showCurrentGauge();
    }
 
}
 
class Car {
    static String name="뽀카";
    int gasolinegauge;
    // car(){}
    
    Car(){
        
    }
    Car(int gasolinegauge){
        this.gasolinegauge=gasolinegauge;
    }
}
 
class HybridCar extends Car {
 
    int electronicGauge;
    /*
      HybridCar(){
       super();
        }
     */                              // Car(){}가 없다면 상위클래스 생성자에 필요한 것을 넣어줘야함
    
    HybridCar(int gasolinegauge, int electronicGauge){
        // 조상 클래스의 멤버를 초기화하는 생성자 호출
        // super(gasolinegauge);  // 조상클래스super는 꼭 첫줄에!
        super();
        // 새롭게 정의한 Hybrid 클래스의 멤버를 초기화해줌
        this.electronicGauge=electronicGauge;
        
    }
 
    
}
 
class HybridWaterCar extends HybridCar {
    /*
      
      HybridWaterCar()
      { super(); 
      }
     
     */
    HybridWaterCar(int gasolinegauge, int electronicGauge, int watergauge){
        super(gasolinegauge, electronicGauge);
        this.waterGauge=watergauge;
    }
    
    
    int waterGauge;
 
    public void showCurrentGauge() {
        System.out.println("잔여 가솔린 : " + gasolinegauge);
        System.out.println("잔여 전기 : " + electronicGauge);
        System.out.println("잔여 water : " + waterGauge);
    }
}
cs

'JAVA > basic' 카테고리의 다른 글

인터페이스 / interface / implements  (0) 2020.10.20
추상클래스 / abstract class  (0) 2020.10.20
오버라이딩 Override / Overriding & 다형성  (0) 2020.10.16
[Singleton] 싱글톤 / 싱글턴 패턴  (0) 2020.10.15
getter / setter  (0) 2020.10.15
접근제어 [ private / public / protected / default ]  (0) 2020.10.15
import  (0) 2020.10.15

객체 중에는 전체 시스템을 통틀어 딱 하나만 존재해야 하는 것들이 있다.

그럴 때 이용하는 싱글턴/톤 패턴

 

'JAVA > basic' 카테고리의 다른 글

추상클래스 / abstract class  (0) 2020.10.20
오버라이딩 Override / Overriding & 다형성  (0) 2020.10.16
상속 / extends  (0) 2020.10.15
getter / setter  (0) 2020.10.15
접근제어 [ private / public / protected / default ]  (0) 2020.10.15
import  (0) 2020.10.15
배열과 메소드  (0) 2020.10.13

Getter 와 Setter 메서드 : 

  1. getter메서드
    • 반드시 소문자 get을 접두사로 사용 
    • get다음에 이어지는 단어의 첫번째 글자는 반드시 대문자로 작성
    • 반드시 리턴값이 있어야 한다 (void 불가)
    • 매개변수가 없어야 한다.
  2. setter메서드
    • 반드시 소문자 set을 접두사로 사용
    • set다음에 이어지는 단어의 첫번째 글자는 반드시 대문자로 작성
    • 반드시 리턴값이 없어야 한다 (반드시 void형 이어야 한다)
    • 반드시 매개변수가 있어야한다

hsprnote.blogspot.com/2017/03/java-getter-setter.html

 

JAVA - getter / setter 메서드

일반적으로 클래스에 선언된 맴버변수를 외부에서 수정하려면 인스턴스를 생성후 해당 변수명을 호출해와 직접적으로 수정해줬다. 하지만 위와 같은 방법으로 맴버변수값을 변경할 경우 정보�

hsprnote.blogspot.com

 

 

 

'JAVA > basic' 카테고리의 다른 글

오버라이딩 Override / Overriding & 다형성  (0) 2020.10.16
상속 / extends  (0) 2020.10.15
[Singleton] 싱글톤 / 싱글턴 패턴  (0) 2020.10.15
접근제어 [ private / public / protected / default ]  (0) 2020.10.15
import  (0) 2020.10.15
배열과 메소드  (0) 2020.10.13
2차원 배열 / 다차원 배열  (0) 2020.10.13

 

 

(default는 아무것도 안적힌 기본 상태일때를 말함)

제어자 같은 클래스 같은 패키지 자손 클래스 전체
public [공용멤버] O O O O
protected O O O  
default [패키지멤버] O O    
private [전용멤버] O      

 

 

 

// 제어자 + [class/변수/메서드/생성자] 

Class 인스턴스 생성 제어 / 클래스를 다른클래스가 사용하게 하거나 못하게 하거나를 제어
변수 변경, 참조, 읽기 제어
메서드 호출 제어
생성자 인스턴스 생성 제어

 

// 제어자의 조합

대상 사용가능한 제어자
클래스 public, (default), final, abstract
메서드 모든 접근 제어자, final, abstract, static
멤버변수 모든 접근 제어자, final, static
지역변수 final

 

1. 메서드에 static과 abstract를 함께 사용할 수 없다.

-  static메서드는 몸통(구현부)이 있는 메서드에만 사용할 수 있기 때문이다. 

 

2. 클래스에 abstract와 final을 동시에 사용할 수 없다.

- 클래스에 사용되는 final은 클래스를 확장할 수 없다는 의미이고, abstract는 상속을 통해서 완성되어야 한다는 의미이므로 서로 모순되기 때문이다. 

 

3. abstract메서드의 접근제어자가 private일 수 없다.

 abstract메서드는 자손클래스에서 구현해주어야 하는데 접근 제어자가 private이면, 자손클래스에서 접근할 수 없기 때문이다.

 

4. 메서드에 private과 final을 같이 사용할 필요는 없다.

- 접근 제어자가 private인 메서드는 오버라이딩될 수 없기 때문이다. 이 둘 중 하나만 사용해도 의미가 충분하다.

 

 

~예제~

'JAVA > basic' 카테고리의 다른 글

상속 / extends  (0) 2020.10.15
[Singleton] 싱글톤 / 싱글턴 패턴  (0) 2020.10.15
getter / setter  (0) 2020.10.15
import  (0) 2020.10.15
배열과 메소드  (0) 2020.10.13
2차원 배열 / 다차원 배열  (0) 2020.10.13
변수의 초기화 / 초기화 블럭  (0) 2020.10.08

sql에도 있고 util에 있는 Date처럼 내가 원하는 애들이 이름이 같으면 이상한걸 쓸수 있으니 주의해야 한다.

 

'JAVA > basic' 카테고리의 다른 글

[Singleton] 싱글톤 / 싱글턴 패턴  (0) 2020.10.15
getter / setter  (0) 2020.10.15
접근제어 [ private / public / protected / default ]  (0) 2020.10.15
배열과 메소드  (0) 2020.10.13
2차원 배열 / 다차원 배열  (0) 2020.10.13
변수의 초기화 / 초기화 블럭  (0) 2020.10.08
객체지향 : class 생성  (0) 2020.10.07

+ Recent posts