title: "Standard simple" interfaces in Java?
body: <p>So here in Java I've written a typical class, to send json to a rest server.  (I'll include the whole class below for clarity.) So that's a file <strong>"Fetcher.java"</strong></p>
  
  <p>Now for the callback you need an interface.  The interface is trivial, just one function with a string.</p>
  
  <pre><code>public interface FetcherInterface {
      public void fetcherDone(String result);
  }
  </code></pre>
  
  <p>Annoyingly you need a whole file for that, <strong>"FetcherInterface.java"</strong></p>
  
  <p>So this interface is nothing but "one callback with a string".  Often all you need is just "one callback with no arguments".</p>
  
  <p>In fact ........ <strong>are there some sort of standard interfaces I can use</strong>, or something like that?</p>
  
  <p>It seems kind of annoying to have to put in a whole interface for such a simple "standard" interface.</p>
  
  <p>What's the deal on this?  What's the javaly solution?</p>
  
  <p>It seems you <strong>CAN NOT put it in the same file</strong>:</p>
  
  <p><a href="https://i.stack.imgur.com/bHQ29.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/bHQ29.png" alt="enter image description here"></a></p>
  
  <p>Perhaps I misunderstand something there.  If you could put it in the same file, that would be convenient at least.</p>
  
  <p>(Lambdas are not yet practically available. Anyway, sometimes you want an interface.)</p>
  
  <hr>
  
  <p>Just for clarity, here's how you call the class</p>
  
  <pre><code>    JSONObject j = new JSONObject();
      try {
          j.put("height", 2.1);
          j.put("width", 2.5);
          j.put("command", "blah");
      } catch (JSONException e) {
          e.printStackTrace();
      }
      new Fetcher("mobile/login", j, new FetcherInterface() {
                  @Override
                  public void fetcherDone(String result) {
                      Log.d("DEV","all done");
                      doSomething(result);
                  }
          }
      ).execute();
  </code></pre>
  
  <p>or indeed</p>
  
  <pre><code>public class HappyClass extends Activity implements FetcherInterface {
  ...
  
  private void someCall() {
      JSONObject j = new JSONObject();
      try {
          j.put("height", 2.1);
          j.put("width", 2.5);
          j.put("command", "blah");
      } catch (JSONException e) {
          e.printStackTrace();
      }
      new Fetcher("mobile/data", j, this).execute();
      devBlank();
  }
  
  @Override
  public void fetcherDone(String result) {
      Log.d("DEV","all done" +result);
      doSomething(result);
  }
  </code></pre>
  
  <p>Here's the whole class...  Fetcher.java file</p>
  
  <pre><code>public class Fetcher extends AsyncTask&lt;Void, Void, String&gt; {
  
      private String urlTail;
      private JSONObject jsonToSend;
      private FetcherInterface callback;
  
      // initializer...
      Fetcher(String ut, JSONObject toSend, FetcherInterface cb) {
          urlTail = ut;
          jsonToSend = toSend;
          callback = cb;
      }
  
      @Override
      protected String doInBackground(Void... params) {
  
          HttpURLConnection urlConnection = null; // declare outside try, to close in finally
          BufferedReader reader = null;           // declare outside try, to close in finally
          String rawJsonResultString = null;
          String json = jsonToSend.toString();
  
          Log.d("DEV","the json string in Fetcher is " +json);
  
          try {
              URL url = new URL("https://falcon.totalfsm.com/" + urlTail);
  
              Log.d("DEV","the full URL in Fetcher is " +url);
  
              // open a json-in-the-body type of connection.......
              urlConnection = (HttpURLConnection) url.openConnection();
              urlConnection.setRequestMethod("POST");
              urlConnection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
              urlConnection.setDoOutput(true);
              urlConnection.setDoInput(true);
              urlConnection.setConnectTimeout(5000);
              // urlConnection.setDoOutput(false); // can be important?
  
              urlConnection.connect();
  
              OutputStream os = urlConnection.getOutputStream();
              os.write(json.getBytes("UTF-8"));
              os.close();
  
              // annoyingly, you have to choose normal versus error stream...
              InputStream inputStream;
              int status = urlConnection.getResponseCode();
              if (status != HttpURLConnection.HTTP_OK)
                  inputStream = urlConnection.getErrorStream();
              else
                  inputStream = urlConnection.getInputStream();
              if (inputStream == null) { // nothing to do.
                  return null;
              }
  
              StringBuffer buffer = new StringBuffer();
              reader = new BufferedReader(new InputStreamReader(inputStream));
              String line;
              while ((line = reader.readLine()) != null) { // adding newlines makes debugging easier
                  buffer.append(line + "\n");
              }
  
              if (buffer.length() == 0) { // stream was empty
                  return null;
              }
  
              rawJsonResultString = buffer.toString();
              return rawJsonResultString;
  
          } catch (IOException e) {
              Log.e("PlaceholderFragment", "Error ", e);
              return null;
          } finally{
              if (urlConnection != null) {
                  urlConnection.disconnect();
              }
              if (reader != null) {
                  try {
                      reader.close();
                  } catch (final IOException e) {
                      Log.e("PlaceholderFragment", "Error closing stream", e);
                  }
              }
          }
      }
  
      @Override
      protected void onPostExecute(String s) {
          super.onPostExecute(s);
          Log.d("DEV", "Fetcher done");
          if (s==null) {
              Log.d("DEV","applying anti-null measures in Fetcher!");
              s = "message from app communications layer: 'null' returned from servers for that call at " +urlTail;
          }
          callback.fetcherDone(s);
      }
  }
  </code></pre>