HostAndPort implements Serializable { public static HostAndPort fromParts(String host, int port) { if (!isValidPort(port)) { throw new IllegalArgumentException(String.format("Port out of range: %s", port)); } HostAndPort parsedHost = fromString(host); if (parsedHost.hasPort()) { throw new IllegalArgumentException(String.format("Host has a port: %s", host)); } return new HostAndPort(parsedHost.host, port, parsedHost.hasBracketlessColons); } private  HostAndPort(String host, int port, boolean hasBracketlessColons); String getHost(); boolean hasPort(); int getPort(); int getPortOrDefault(int defaultPort); static HostAndPort fromParts(String host, int port); static HostAndPort fromHost(String host); static HostAndPort fromString(String hostPortString); HostAndPort withDefaultPort(int defaultPort); HostAndPort requireBracketsForIPv6(); @Override boolean equals(Object other); @Override int hashCode(); @Override String toString();  }
@Test public void testFromParts() { HostAndPort hp = HostAndPort.fromParts("gmail.com", 81); assertEquals("gmail.com", hp.getHost()); assertTrue(hp.hasPort()); assertEquals(81, hp.getPort()); try { HostAndPort.fromParts("gmail.com:80", 81); fail("Expected IllegalArgumentException"); } catch (IllegalArgumentException expected) { } try { HostAndPort.fromParts("gmail.com", -1); fail("Expected IllegalArgumentException"); } catch (IllegalArgumentException expected) { } }