Can I acess a final object's methods? - java

I have to declare a parameter on my method final to access it through a Runnable but can I still access the methods? I need to edit the object a bit. I can't seem to find anything that can help me with this question, so hopefully this isn't a stupid question. Thanks in advanced!

An object is not final, but its reference is. So you can easily access its methods (if any) to modify the object.

You can change the state of the object, even if it is marked final. When you mark a reference variable final, you can't reassign it to another object, but you can definitely change the state of the object to which it is already referring by calling its methods.

Yes you can. Check this example
public class SampleA
{
private static final SampleB sampleB = new SampleB();
public static void main(String[] args)
{
System.out.println( sampleB.toString() );
sampleB.setM1( "1" );
System.out.println( sampleB.toString() );
}
}
public class SampleB
{
private String m1;
private String m2;
public String getM1()
{
return m1;
}
public void setM1(String m1)
{
this.m1 = m1;
}
public String getM2()
{
return m2;
}
public void setM2(String m2)
{
this.m2 = m2;
}
public String toString()
{
final String TAB = " ";
String retValue = "SampleB ( "
+ "m1 = " + this.m1 + TAB
+ "m2 = " + this.m2 + TAB
+ " )";
return retValue;
}
}

Related

Is there a way to make Dozer map fields without getter or setters? (Or, what mapper can do this?)

Here's an article on Dozer: https://www.baeldung.com/dozer. It's a mapper that uses reflection to map same-name fields from one object to another (of a completely unrelated class).
I was wondering if this works flexibly with private fields, getters, and setters. That is,
Will private String a map to another object's private String a without either having any getters or setters?
What if only one side has a getter or setter (and the private field is named something different to make sure it's not directly accessing private fields)?
What if one has a getter and the other has a setter for totally mismatching private fields? (But the getter and setter names match.)
I wrote a test program to run in https://www.jdoodle.com/online-java-compiler:
import org.dozer.DozerBeanMapper;
public class Main {
public static class MySource {
// a -> a
private String a;
// getB() -> b
private String hidden_b;
public String getB() { return hidden_b; }
// c -> setC(c)
private String c;
// getD() -> setD(d)
private String hidden_d;
// proper getters and setters on both sides
private String proper;
public String getProper() { return proper; }
// public void setProper(String proper_) { proper = proper_; }
public MySource() {
a = "A Room with a View";
hidden_b = "The Bridge of San Luis Rey";
c = "Civilwarland in Bad Decline";
hidden_d = "Darkness at Noon";
proper = "This should copy, at minimum.";
}
public void print() {
System.out.println("Source");
System.out.println("================================");
System.out.println("a = " + a);
System.out.println("hidden_b = " + hidden_b);
System.out.println("c = " + c);
System.out.println("hidden_d = " + hidden_d);
System.out.println("--------------------------------");
System.out.println("proper = " + proper);
System.out.println("");
}
}
public static class MyTarget {
private String a;
private String b;
private String hidden_c;
private String hidden_e;
public void setC(String param) { hidden_c = param; }
public void setD(String param) { hidden_e = param; }
private String proper;
// public String getProper() { return proper; }
public void setProper(String proper_) { proper = proper_; }
public MyTarget() {}
public void print() {
System.out.println("Target");
System.out.println("================================");
System.out.println("a = " + a);
System.out.println("b = " + b);
System.out.println("hidden_c = " + hidden_c);
System.out.println("hidden_e = " + hidden_e);
System.out.println("--------------------------------");
System.out.println("proper = " + proper);
System.out.println("");
}
}
public static void main(String args[]) {
MySource s = new MySource();
s.print();
System.out.println("Now dozing...");
System.out.println("");
MyTarget t = new DozerBeanMapper().map(s, MyTarget.class);
t.print();
}
}
Note that to run the above code you must add a maven dependency:
Group ID: net.sf.dozer
Artifact ID: dozer
Version: 5.5.1
And also you must try executing a few times because of random timeouts depending on whether the dependency loads fast enough.
Anyway, my output was:
Source
================================
a = A Room with a View
hidden_b = The Bridge of San Luis Rey
c = Civilwarland in Bad Decline
hidden_d = Darkness at Noon
--------------------------------
proper = This should copy, at minimum.
Now dozing...
Target
================================
a = null
b = null
hidden_c = null
hidden_e = null
--------------------------------
proper = This should copy, at minimum.
So, it appears Dozer only works through a getter on the source and a setter on the target, which is disappointing. Or, I'm not using it correctly!
Is there a way to make Dozer more flexible? Or, another mapper library that can achieve this?
Okay, here are my findings. Hopefully this helps someone.
Dozer 5.5.1 was supposed to be able to do this via "class-level is-accessible." However, there was a bug. It was fixed for future releases, e.g. Dozer 6.1+. (The package moved to a new group, org.github.dozermapper.) The steps were a little complicated though, and eventually I gave up to try ModelMapper, which was much nicer. So here's my code.
Include this package:
Group ID: org.modelmapper
Artifact ID: modelmapper
Version: 2.3.2
Here's how to use it:
import org.modelmapper.ModelMapper;
import org.modelmapper.config.Configuration;
public class Main {
public static class MySource {
// a -> a
private String a;
// getB() -> b
private String hidden_b;
public String getB() { return hidden_b; }
// c -> setC(c)
private String c;
// getD() -> setD(d)
private String hidden_d;
// proper getters and setters on both sides
private String proper;
public String getProper() { return proper; }
// public void setProper(String proper_) { proper = proper_; }
public MySource() {
a = "A Room with a View";
hidden_b = "The Bridge of San Luis Rey";
c = "Civilwarland in Bad Decline";
hidden_d = "Darkness at Noon";
proper = "This should copy, at minimum.";
}
public void print() {
System.out.println("Source");
System.out.println("================================");
System.out.println("a = " + a);
System.out.println("hidden_b = " + hidden_b);
System.out.println("c = " + c);
System.out.println("hidden_d = " + hidden_d);
System.out.println("--------------------------------");
System.out.println("proper = " + proper);
System.out.println("");
}
}
public static class MyTarget {
private String a;
private String b;
private String hidden_c;
private String hidden_e;
public void setC(String param) { hidden_c = param; }
public void setD(String param) { hidden_e = param; }
private String proper;
// public String getProper() { return proper; }
public void setProper(String proper_) { proper = proper_; }
public MyTarget() {}
public void print() {
System.out.println("Target");
System.out.println("================================");
System.out.println("a = " + a);
System.out.println("b = " + b);
System.out.println("hidden_c = " + hidden_c);
System.out.println("hidden_e = " + hidden_e);
System.out.println("--------------------------------");
System.out.println("proper = " + proper);
System.out.println("");
}
}
public static void main(String args[]) {
ModelMapper modelMapper = new ModelMapper();
modelMapper.getConfiguration()
.setFieldMatchingEnabled(true)
.setFieldAccessLevel(Configuration.AccessLevel.PRIVATE);
MySource s = new MySource();
s.print();
System.out.println("Now dozing...");
System.out.println("");
MyTarget t = modelMapper.map(s, MyTarget.class);
t.print();
}
}
Here's my output:
Source
================================
a = A Room with a View
hidden_b = The Bridge of San Luis Rey
c = Civilwarland in Bad Decline
hidden_d = Darkness at Noon
--------------------------------
proper = This should copy, at minimum.
Now dozing...
Target
================================
a = A Room with a View
b = The Bridge of San Luis Rey
hidden_c = Civilwarland in Bad Decline
hidden_e = null
--------------------------------
proper = This should copy, at minimum.
The fourth case didn't copy over but I don't really care about that case. I think it can easily achieved with a different ModelMapper configuration though. Maybe try LOOSE copying. Or worst case, manually bind the getter and setter methods in the config.
Dozer by default uses getters and setters, however you can tell Dozer (via mapping) to access the fields directly
http://dozer.sourceforge.net/documentation/custommethods.html
BTW, Dozer 5 and 6 contains an API based mapping as well.

Java Variable from other class

I have 3 classes: Main, AutoHuur, Auto. Everythign works but 1 thing. I can't seem to get the "Prijs" variable from my Auto.class to display in my toString in my AutoHuur.class. It keeps showing up as 0. Why is this? (I know I initialize it to 0 if it's a null, but why is it a null and not the value from the Auto.class variable prijsPerDag?) Thank you
Main.class:
public class Main{
public static void main(String[] args) {
AutoHuur ah1 = new AutoHuur();
System.out.println("Eerste autohuur:\n" + ah1 + "\n");
Klant k = new Klant("Mijnheer de Vries");
k.setKorting(10.0);
ah1.setHuurder(k);
Auto a1 = new Auto("Peugeot 207", 50.0);
ah1.setGehuurdeAuto(a1);
ah1.setAantalDagen(4);
System.out.println("Eerste autohuur:\n" + ah1 + "\n");
AutoHuur ah2 = new AutoHuur();
Auto a2 = new Auto("Ferrari", 3500.0);
ah2.setGehuurdeAuto(a2);
ah2.setHuurder(k);
ah2.setAantalDagen(1);
System.out.println("Tweede autohuur:\n" + ah2 + "\n");
System.out.println("Gehuurd: " + ah1.getGehuurdeAuto());
System.out.println("Gehuurd: " + ah2.getGehuurdeAuto());
}
}
Autohuur.class:
public class AutoHuur {
private Klant huurder;
private Auto gehuurdeAuto;
private Auto prijs;
private Integer aantalDagen;
public AutoHuur(){
}
public void setHuurder(Klant nwH){
huurder = nwH;
}
public void setGehuurdeAuto(Auto nwGA){
gehuurdeAuto = nwGA;
}
public Auto getGehuurdeAuto(){
return gehuurdeAuto;
}
public Auto getPrijs(){
return prijs;
}
public void setAantalDagen(Integer nwD){
aantalDagen = nwD;
}
public String toString(){
String s = "";
if (gehuurdeAuto == null){
s = s + "er is geen auto bekend\n"; }
else {
s = s + gehuurdeAuto; }
if (huurder == null){
s = s + "er is geen huurder bekend\n"; }
else {
s = s + huurder; }
if (aantalDagen == null){
s = s + "aantal dagen: 0"; }
else {
s = s + "aantal dagen: " + aantalDagen; }
if (prijs == null){
s = s + " en dat kost 0.0"; }
else {
s = s + " en dat kost" + prijs; }
return s;
}
}
Auto.class:
public class Auto {
private String type;
private Double prijsPerDag;
public Auto(String tp, Double nwPr){
type = tp;
prijsPerDag = nwPr;
}
public void setPrijsPerDag(Double prPd){
prijsPerDag = prPd;
}
public Double getPrijsPerDag(){
return prijsPerDag;
}
public String toString(){
String s = type + " met prijs per dag: " + prijsPerDag + "\n";
return s;
}
}
In AutoHuur.class you can get your prijsPerDag variable from Auto.class using an Auto object, e.g.:
gehuurdeAuto.getPrijsPerDag()
You can calculate the price:
aantalDagen * gehuurdeAuto.getPrijsPerDag()
Is this what would you like to do?
You have to remove the first System.out becasuse in Main.java your instance AutoHuur is empty, so when your want to print the result , the out will be values empty.
The variable prijs is an object, which is initialized to null when an instance of AutoHuur is created. Since prijs is never set, it is always null.
That's why prijs == null always evaluates to true.
You need to set prijs somewhere.
It seems that you need to work on your design desicions. You are, for example, using an Auto class name, while it is in fact a link between a daily charge and a car type. If each link is represented by such an object (in your case Auto), then it absolutely makes no sense to have more than one instance.
For example,
new Auto("Peugeot", 40.0);
new Auto("Peugeot", 40.0);
is technically perfectly valid, but it is just not logical.
Furthermore, if a class holds data of some kind, then it's good to delegate operations upon that data also to that class.
class Auto {
private String type;
private double pricePerDay;
public double calculateTotalPrice(int numberOfDays) {
return numberOfDays * this.pricePerDay;
}
}

Difference between Object and variable Object [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 6 years ago.
I'm trying to get the length of seznam2 by using int postle in Stanovanje. However, the variable getPostle() does not pass and I get Exception in thread "main" java.lang.NullPointerException error for this line:
private String[] seznam2 = new String[getStanovanje().getPostle()].
I would also like to know when to use:
Stanovanje stanovanje = new Stanovanje();
or
private Stanovanje stanovanje1;
Here is my code:
Potovanje.java
public class Potovanje {
Stanovanje stanovanje = new Stanovanje();
private Stanovanje stanovanje1;
private String datumOdhoda;
private int trajanje;
private Popotnik[] popotnik;
private ArrayList<Popotnik> seznam = new ArrayList<>();
private String[] seznam2 = new String[getStanovanje().getPostle()];
public Potovanje(String datumOdhoda, int trajanje){
this.datumOdhoda = datumOdhoda;
this.trajanje = trajanje;
}
public void setStanovanje(Stanovanje stanovanje1){
this.stanovanje1 = stanovanje1;
}
public Stanovanje getStanovanje(){
return stanovanje1;
}
public void setPopotnik(Popotnik[] popotnik){
this.popotnik = popotnik;
}
public Popotnik[] getPopotnik(){
return popotnik;
}
public ArrayList<Popotnik> getSeznam(){
return seznam;
}
public void setSeznam2(String[] seznam2){
this.seznam2 = seznam2;
}
public String[] getSeznam2(){
return seznam2;
}
public void dodajPotnika(Popotnik[] popotnik){
//System.out.println("postle: " + stanovanje.getPostle());
for(int i=0; i<getSeznam2().length; i++){
//System.out.println("wadap");
setPopotnik(popotnik);
seznam.add(getPopotnik()[i]);
}
}
public String toString(){
return "datumOdhoda: " + datumOdhoda + "\n" + "trajanje: " + trajanje + "\n" + "popotnik: " + getPopotnik();
}
}
Stanovanje.java
public class Stanovanje {
private int postle;
public Stanovanje(){
}
public Stanovanje(int postle){
this.postle = postle;
}
public void setPostle(int postle){
this.postle = postle;
}
public int getPostle(){
return postle;
}
public String toString(){
return "postle: " + postle;
}
}
The difference between 1 and 2:
/*1*/ Stanovanje stanovanje = new Stanovanje();
/*2*/ private Stanovanje stanovanje1;
is:
1 : has the default visibility (which is "package-private") and is immediately initialized. ( not null)
2 : has private visibility and is not initialized ( thus == null until otherwise initialized )
When to use each of those is hard to answer because there maybe a lot of cases where you'd prefer the one or the other.
If you use the second, you should initialize it in the constructor. Either by creating an instance there or by initialize it to a CTOR-Argument. Otherwise your object is not properly initialized and usage can lead to what you encountered: side-effects like an NPE.
In some cases (heavy objects that are rarely actually needed) it can be useful to leave them uninitialized until really needed (sometimes referred to as "lazy loading"). One would then use a getter that checks if the field has been initialized and do so if not before returning it.
About visibility you can read here: Controlling Access to Members of a Class (Oracle Documentation)
Oracles "rule of thumb" there:
Use private unless you have a good reason not to.

How to return a private variable

Ok so I'm trying to get a better understanding of how to return a private variable from a class that I have created. I've only provided a small snippet of my main program to explain my question, so if more information is needed please let me know. My goal is to return a string from the class (working great), but also be able to return the private variables individually as needed (example used below is "flight_number").
public class Flights {
private String dest_city, dest_state, departureDate, departureTime;
private int flight_number;
public Flights(String city, String state, String dDate, String dTime, int flightNumber) {
dest_city = city;
dest_state = state;
departureDate = dDate;
departureTime = dTime;
flight_number = flightNumber;
}
public String toString() {
return "Flight number: " + flight_number + " Destination: " + dest_city + "," + dest_state + " Departing on:" + departureDate + " at" + departureTime + ".";
}
}
public class dummy {
public static void main(String[] args) {
// Uses the constructor to set values
Flights flight1 = new Flights("Houston", "Texas", "12/20/2014", "12:40 pm", 100);
System.out.println(flight1);
System.out.println(flight_number); // Error: `flight_number` cannot be resolved to a variable.
}
}
You need to add a public getter in Flights and call it from main:
public class Flights {
// all the private fields
public int getFlightNumber() {
return this.flight_number;
}
}
In Main:
public static void main(String[] args) {
Flights flight1 = new Flights("Houston", "Texas"); //...
System.out.println(flight1);
System.out.println(flight1.getFlightNumber()); // call the getter
}
You should start with an editor like eclipse and that should help you get started quickly. Getters and Setters is what you need, but start with Eclipse and you should do better.

Static - Non-Static methods in Java

I got a noob question concerning Static vs. Non-Static Methods.
In this example I parse Data out and want to write it to my DB. I was doing fine as long as I declared the method getData() static. But now when im invoking Database.insert(x,y,z) - the static-non static error comes into play. I just can't wrap my thoughts around the problem how to solve this issue.
Can anyone explain to me, how I can write those variables into my DB? your help is highly valued and will help me advance in java.
EDIT:
Error message saying:
Cannot make a static reference to the non-static method insert(String, String, String, String) from the type Database
Code:
package org.jsoup.examples;
import java.io.*;
import org.jsoup.*;
import org.jsoup.nodes.*;
import org.jsoup.select.Elements;
import java.io.IOException;
/**
* Example program to list links from a URL.
*/
public class parseEasy {
String companyName = "Platzhalter";
String jobTitle = "Platzhalter";
String location = "Platzhalter";
String timeAdded = "Platzhalter";
public static void main(String[] args) throws IOException
{
Database connect = new Database();
connect.OpenConnectionDB();
getData();
connect.closeConnectionDB();
}
// FIRMENNAME
public static void getData() throws IOException
{
int count = 0;
Document document = Jsoup.parse(new File("C:/Talend/workspace/WEBCRAWLER/output/keywords_SOA.txt"), "utf-8");
Elements elements = document.select(".joblisting");
for (Element element : elements)
{
// Counter for Number of Elements returned
count++;
// Parse Data into Elements
Elements jobTitleElement = element.select(".job_title span");
Elements companyNameElement = element.select(".company_name span[itemprop=name]");
Elements locationElement = element.select(".locality span[itemprop=addressLocality]");
Elements dateElement = element.select(".job_date_added [datetime]");
// Strip Data from unnecessary tags
String companyName = companyNameElement.text();
String jobTitle = jobTitleElement.text();
String location = locationElement.text();
String timeAdded = dateElement.text();
Database.insert(companyName, jobTitle, timeAdded, location);
// Test output
System.out.println("Firma:\t"+ companyName + "\t" + jobTitle + "\t in:\t" + location + " \t Erstellt am \t" + timeAdded + "\t. Eintrag Nummer:\t" + count);
}
}
/* public void writeDB(String a,String b,String c,String d){
Database.insert(a, b, c, d);
}
String getcompanyName(){
return companyName;
}
String getjobTitle(){
return jobTitle; }
String gettimeAdded(){
return timeAdded; }
String getlocation(){
return location; }
*/
}
Static and Non-Static also have 2, perhaps better names.
Static is also known as Class-Level, and Non-Static is Instance-Level
Example:
class SomeClass {
static void staticPrint() {
// ^^^^^^^^^^^ static
System.out.println("Hello from static");
}
void instancePrint() {
// ^^^^ not static
System.out.println("Hello from non-static");
}
}
So here's where these two types of methods differ:
SomeClass obj = new SomeClass();
SomeClass.staticPrint(); // prints "Hello from static"
SomeClass.instancePrint(); // throws an error
obj.staticPrint(); // throws an error
obj.instancePrint(); // prints "Hello from non-static"
That's it. That's the difference between static and non-static
One works directly from the class, the other works from the object you create when you new it

Categories

Resources